Hi Vlasta, I get a null object error when running a script that references Document.LayeredImage in the Configuration section. I suppose Document objects haven't been initialized.
I was trying to accomplish Configuration.Add1ofNPicker() using the names of the documents layers. Am I overlooking something?
ps: Thank you for your response to my previous question on getting the foreground color.
EDIT: After a bit of trying, I see that I'm not understanding the proper usage of the LayeredImage property much.
When I put
var layers = Document.LayeredImage;
'layers' is lazily instantiated, so no null check occurs. But if I next try
var layer = layers.GetLayer(0);
or
var layer = Document.LayeredImage.GetLayer(0);
I get errors:
'layers' is null or not an object
'Document.LayeredImage' is null or not an object
I'm clueless as to how I can access a layer. The documentation provides that LayeredImage is exposed as a property of the Document object. I guess a Document is some sort of static object. My jscript is poor, meh. I understand that a layer can be worked with as a Document object.
pps: It's all good.
You are understanding it correctly. The problem may be in the Document. If you are using the "Custom operation" button or menu item, it is configured to only work with the active layer to simplify things. So, the Document you get is just the selected layer, which is not a LayeredImage.
You would have to right-click the toolbar with the javascript operation, go to the configuration and remove the "Extract document part" element from the hierarchy. Though this may be a bit hard to do as there are too many clickable things. Let me know if you succeeded or where you got stuck.
Hi, Vlasta.
Instead of trying to delete "Extract document part" element from the command hierarchy, and recreating the entire toolbar, I tried to add a new toolbar item to the TBIMAGE toolbar. I used export and import buttons to copy the JSOperation RealWorld Menu Command to the toolbar. I get a "Failed to load DLL" error.
Sorry I let this sit for a week.
What I am trying to accomplish:
On one layer, the base, is an image object with alpha like a logo or icon or such. The image may be made of separate components, like text.
One another layer, is an image with a pattern, texture, or picture.
Applying the image layer to the base layer - requires getting the alpha value of each pixel in the base layer. If zero, do nothing. Else get the pixel color of the texture layer and set the base image pixel color, thus retaining the exact original alpha value.
This might be slow using JavaScript - swapping back and forth between layers, but the average image is usually 256x256.
Two other things I wanted to accomplish with the script(s); draw the result to a new layer. Probably not so hard, once it's clear how to use the LayeredImage interface/property. Additionally, in the Configuration editor, I was hoping to use the GetLayerName() method to create a string[], and present the layers with Add1ofNPicker(). This too seems simple in theory.
I could do the whole thing in C# and VS, but I really want to keep this in the RealWorld editor where I can perform operations without opening a second workflow.
Well, whatever the problem is, I can't get off the launch pad with this one.
Yet.
thx, Parrish
ps, RealWorld graphic products are the best=) 99% of the graphic work I do is done within your terrific editor. If all my software made as much sense to me, I'd always be happy in front of the computer monitor! Best, low prices too=)
I tried what you described and here is the code.
Configuration:
var li = Document.LayeredImage;
var n = li.Layers;
var names = [];
for (var i = 0; i < n; ++i)
names.push(li.GetLayerName(i));
Configuration.Add1ofNPicker("l1", "Layer 1", "", names, 0, true);
Configuration.Add1ofNPicker("l2", "Layer 2", "", names, n > 1 ? 1 : 0, true);
Execution:
var li = Document.LayeredImage;
var nX = li.sizeX;
var nY = li.sizeY;
var n = li.Layers;
var l1 = li.GetLayer(Configuration.l1);
var l2 = li.GetLayer(Configuration.l2);
// create new layer
var wiz = Application.CreateWizard("35AFBDB5-1B26-4195-8786-83C8E1CBC08E");
wiz.SizeX = nX;
wiz.SizeY = nY;
li.CreateLayer(-1, wiz, "35AFBDB5-1B26-4195-8786-83C8E1CBC08E");
var newlayer = li.GetLayer(0);
// copy l2 to new layer
Blender.Compose(newlayer, 0, 0, nX, nY, l2, 0, 0, 0, Blender.OpSrc);
// copy alpha channer from l1 to the new layer
Blender.Compose(newlayer, 0, 0, nX, nY, l1, 0, 0, 0, Blender.OpMapChannels,
Blender.MapChannels(Blender.ChEmpty, Blender.ChEmpty, Blender.ChEmpty, Blender.ChA,
Blender.ChEmpty, Blender.ChEmpty, Blender.ChEmpty, Blender.ChA));
I occasionally encounter the error you describe and I do not know why. It seems that the Microsoft JavaScript engine is sometimes confused when dealing with the global objects exposed by RW. It usually happens with the Context object and it helps to just mention the global object in the script before actually using it by just typing
Context;
in the beginning of the script.
Maybe the problem was with removing the "Extract document part" item?
Works as intended. I'm proud of you. I tried it in RW Paint 2011, to avoid destroying my TBEFFECT toolbar. I exported all the RWCommands from the toolbar; changed the Configuration Root to Command List; added Document:Extract Document Part to the list; re-imported the native commands to its Inner list; and was good to go.
In the JavaScript, I removed the optional arguments from each method, as they each produced an error. Probably the 2011 version.
This "transfer effect" is something that can nearly be performed by other means in RW, but I wanted the exact alpha value, and you found it.
Thanks Vlasta, for being so supportive.
If you use the portable version, you can just copy the whole folder and use it for experiments. All settings are kept in a subfolder.