SetSourceImage
Moderators: Víctor Paredes, Belgarath, slowtiger
SetSourceImage
I'm writing my first lua script here, and I'm having a bit of trouble.
To import an image, I'm using the
layer.SetSourceImage(path)
Do I need the full path to the file? Or can it just be the name of the file if it's in the working directory?
I looked at janimatic's image loading script and it's a full path there, so I put a full hardcoded path into the argument:
layer.SetSourceImage("/home/bla/bla/full/path/to/image.jpg")
but I'm still getting the error:
attempt to call method 'SetSourceImage' (a nil value)
To import an image, I'm using the
layer.SetSourceImage(path)
Do I need the full path to the file? Or can it just be the name of the file if it's in the working directory?
I looked at janimatic's image loading script and it's a full path there, so I put a full hardcoded path into the argument:
layer.SetSourceImage("/home/bla/bla/full/path/to/image.jpg")
but I'm still getting the error:
attempt to call method 'SetSourceImage' (a nil value)
The path has to include everything, including the drive (like "c:\" in windows, or whatever would be an acceptable path to use for command line work in whatever OS you are using. If you want to pick the file, you can use this:
Then you don't have to hard code the path, and it works the same on any OS. All the bits from "local file =" are just some basic error checking, to make sure theres actually a file there, maybe not necessary but idiot-proofing is good, especially if the idiot is your OS. But you're real problem is that it should be "layer:SetSourceImage(...". Note the colon. That means applying "SetSourceImage" to the object "layer". If you use the dot, then it means you have a global value of "layer", with a sub-value that's a function called "SetSourceImage".
Also If you want, I've been building up my library (which goes in the Moho/scripts/utility directory, and you can make you're own for commonly used things) to do all this kind of stuff, just to simplify things. There are 2 functions that relate to this:
There are a few bit's in there for common path manipulation:
That's all stuff I'm doing in a lot of different places, so it's handy. Once you have a function debugged, it also helps save time from tracking down that minor misspelling or capital where it should be lowercase. Lua's awful picky with that stuff, so it saves a lot of hassle in the end.
Was that too much? Anyway, if you don't feel like dealing with some of the wierdness it takes a little while to get used to just yet, feel free to use anything in there, that's what it's for.
If you look my last tweak to Janimatics bulk importer, you can see
Code: Select all
local path = LM.GUI.OpenFile("Choose file")
if (path == "") then
return
end
local file = io.open(path, "r")
if (file == nil) then
print("file doesn't exist!:", path)
return
end
file:close()
Also If you want, I've been building up my library (which goes in the Moho/scripts/utility directory, and you can make you're own for commonly used things) to do all this kind of stuff, just to simplify things. There are 2 functions that relate to this:
Code: Select all
---------------------------------------------------------------------
-- create a new image layer, with an optional name
-- use - newLayer = SF.newImageLayer(moho, "Absolutely Great Image")
-- the name can of course be a string variable
---------------------------------------------------------------------
function SF.newImageLayer(moho, name)
local anImageLayer = moho:LayerAsImage(moho:CreateNewLayer(MOHO.LT_IMAGE) )
if name then
anImageLayer:SetName(name)
end
return anImageLayer
end
---------------------------------------------------------------------
-- Import an image into a new image layer. The "name" parameter is
-- optional, if omitted the filename will be used. The "useExt"
-- parameter is either true or false, and determines, if you don't
-- provide the optional layer "name", if the file extension will be
-- stripped from the layer name.
---------------------------------------------------------------------
function SF.ImportImage(moho, path, useExt, name)
local layer = nil
if name then
layer = SF.newImageLayer(moho, name)
else
local filename = SF.filenameFromPath(path)
if not useExt then
filename = SF.removeExtFromFilename(filename)
end
layer = SF.newImageLayer(moho, filename)
end
layer:SetSourceImage(path)
return layer
end
Code: Select all
function SF.findFromEnd(s, pattern)
local lastChar = string.len(s)
local i = -1
position = nil
while (position == nil) and ((-i) <= string.len(s)) do
position = string.find(s, pattern, i)
if (position == lastChar) then position = nil end
i = i - 1
end
return position
end
function SF.filenameFromPath(path)
local found = SF.findFromEnd(path,"[\\/]")
if found then
return string.sub(path ,found + 1, string.len(path))
end
end
function SF.removeExtFromFilename(filename)
local found = SF.findFromEnd(filename,"[.]")
if found then
return string.sub(filename, 1, found - 1)
end
end
Was that too much? Anyway, if you don't feel like dealing with some of the wierdness it takes a little while to get used to just yet, feel free to use anything in there, that's what it's for.
If you look my last tweak to Janimatics bulk importer, you can see
Brian, thanks for your reply. It looks like your it got chopped off, though.
In my script, I am opening a file that is a list of images I want to import. I was hoping that I could use relative names. I think I'll use your utils as a model to get the path, regardless of platform, and prepend that to the names. I think it's safe to assume that the files are going to be in the same directory as the text file itself.
Thanks again!
jorgy
In my script, I am opening a file that is a list of images I want to import. I was hoping that I could use relative names. I think I'll use your utils as a model to get the path, regardless of platform, and prepend that to the names. I think it's safe to assume that the files are going to be in the same directory as the text file itself.
Thanks again!
jorgy
I don't even remember what else I wrote,some thing like ...you can see that I used a lot of them and it makes the basic program more compact and understandable...
Which can be important. I've been going over some of my 1st scripts to fix 'em up, and some of them have taken me quite a while to figure out what did. That's also why I now use a lot of descriptive variable names. All that "x, y, i, m..." saves on typing but can make things a bear to go back into later.
One way to go about it is to set a global variable that includes your basic path. If you do a LM.GUI.OpenFile it just returns the path. So one way to set it up would be (and again I'm referring to some of my utilities for simplicity):
So you use the OpenFile to choose any old file in the directory you want, extract the extraneous filename, and then strip that off of the fullPath to give you a pointer to the directory. Then you just need to store that somewhere it won't get lost or go away. Then you should be able to use "JORGY_DefaultPath.Path in any script to recall the default path. It's pretty cool that you can store values in a more or less permanent manner.
Which can be important. I've been going over some of my 1st scripts to fix 'em up, and some of them have taken me quite a while to figure out what did. That's also why I now use a lot of descriptive variable names. All that "x, y, i, m..." saves on typing but can make things a bear to go back into later.
One way to go about it is to set a global variable that includes your basic path. If you do a LM.GUI.OpenFile it just returns the path. So one way to set it up would be (and again I'm referring to some of my utilities for simplicity):
Code: Select all
-- put something like this at the top of a "get default path" script:
function JORGY_DefaultPath:SavePrefs(prefs)
prefs:SetString("JORGY_DefaultPath.Path", self.Path)
end
function JORGY_DefaultPath:LoadPrefs(prefs)
self.Path = prefs:GetString("JORGY_DefaultPath.Path", "c:\\")
end--the default setting the first time you use the script /^\
...-- ______________|
function JORGY_DefaultPath:Run(moho)
... --- get your full path using a dummy with LM.GUI.OpenFile
local fullPath = fileInDir --valid filepath
local fileName = SF.filenameFromPath(fullPath) --get file name
local Path = string.sub(fullPath, 1, string.len(fullPath)-string.len(fileName)) --and path
self.Path = Path -- set your permanent (until you run this again) path, that'll
... --be saved in the "moho.user.settings" file
end
While working on my script, I added a little helper to your library.
Feel free to use/abuse, etc.

Code: Select all
function SF:directoryFromPath(path)
local found = SF.findFromEnd(path,"[\\/]")
if found then
return string.sub(path ,1, string.len(path) - found)
end
end
found my problem
Hello,
I found my problem in my script. I was doing a:
when I should have been doing a:
Not quite sure what the difference is, but then my SetSourceImage worked fine. I'm getting to like this lua thing, even if I keep trying to put ";" at the end of each line like the 'ol perl head I am.
I'll get my script cleaned up and post it here.
Thanks 7ft!
I found my problem in my script. I was doing a:
Code: Select all
local layer = moho:CreateNewLayer(MOHO.LT_IMAGE)
Code: Select all
local layer = moho:LayerAsImage(moho:CreateNewLayer(MOHO.LT_IMAGE) )
I'll get my script cleaned up and post it here.
Thanks 7ft!
- Lost Marble
- Site Admin
- Posts: 2356
- Joined: Tue Aug 03, 2004 10:02 am
- Location: Scotts Valley, California, USA
- Contact:
Re: found my problem
If you're familiar with C++, what's going on is that the CreateNewLayer function returns a "generic" layer type (the layer base class in C++). The LayerAsImage function "casts" the generic layer to an image layer type. That way you can access the image-specific features of the layer.jorgy wrote:Not quite sure what the difference is...
Casting layers from a generic type to a specific type is necessary because of the way the Lua API mirrors the underlying C++ data structures.
- Lost Marble
- Site Admin
- Posts: 2356
- Joined: Tue Aug 03, 2004 10:02 am
- Location: Scotts Valley, California, USA
- Contact: