GIMP Script-fu changing default scripts - scripting

I am having issues re-writing one of the default logo scripts in GIMP(using Script-fu based on scheme). For one thing the alpha layer is not shown in the layer browser after the image is shown. I am re-writing the Create Neon Logo script(neon-logo.scm) and I want it to do the following before it displays the new image:
add an alpha channel
change black(background color) to transparent via colortoalpha
return the generated image as an object to be used in another python script(using for loops to generate 49 images)
I have tried modifying the following code to the default script:
(gimp-image-undo-disable img)
(apply-neon-logo-effect img tube-layer size bg-color glow-color shadow) *Generates neon logo
(set! end-layer (car (gimp-image-flatten img))) *Flattens image
(gimp-layer-add-alpha end-layer) *Adds alpha layer as last layer in img(img=the image)
(plug-in-colortoalpha img 0 (255 255 255)) *Uses color to alpha-NOT WORKING
(gimp-image-undo-enable img) *Enables undo
(gimp-display-new img) *Displays new image
For number 3 my python code is this:
for str1 in list1:
for color1 in list3:
img = pdb.script_fu_neon_logo(str1,50,"Swis721 BdOul BT",(0,0,0),color1,0)
But img is a "Nonetype" object. I would like to make it so that instead of displaying the generated image in a new window, it just returns the generated image for use with my python script.
Can anyone help?

Maybe to keep everything more managaeable and readable, you should translate theoriginal script into Python - that way you willhaveno surprises on otherwiser trivial things as variable assignment, picking elements from sequences and so on.
1 and 2) your calls are apparantly correct to flaten an "add an alpha channel " (not "alpha layer",a s you write, please) to the image - but you are calling color-to-alpha to make White (255 255 255) transparemt not black. Trey changing that to (0 0 0) - if it does not work, make]
each of the calls individually, either on script-fu console or on python console, and check what is wrong.
3) Script-fu can't return values to the caller (as can be seen by not having a "return value type" parameter to the register call. That means that scripts in scheme in GIMP can only render thigns on themselves and not be used to compose more complex chains.
That leaves you with 2 options: port the original script to Python-fu (and them just register it to return a PF-IMAGE) - or hack around the call like this, in Python:
create a set with all images opened, call your script-fu, check which of your images currently open is not on the set of images previously opened - that will be your new image:
The tricky part with this is that: there is no unique identifier to an image when you see it from Python-fu - so you 'dhave to compose a value like (name, number_of_layers, size) to go on those comparison sets and even that might not suffice - or youg could juggle with "parasites" (arbitrary data that can be attached to an image). As you can see, having the original script-fu rewriten in Python, since all the work is done by PDB calls, and these translate 1:1, is preferable.

Related

How to display more than one image dynamically with python (pyqt5)?

I'm using python to build an application by PyQt5, the main idea is to display images from a directory and for each image some masks show up next to it to select one of them (i.e. for each image there are different number of masks). So, I want to display these masks in a "container" that can handle this dynamically.
I tried QlistWidget in a scroll area and the masks are displayed as icons in it, but I want to use something else to handle them easier and retrieve any mask as Qpixmap or QImage to use it in another operations without convert it multiple times (which slows down the program)
this is the part that displays the masks (this is the only way that worked with me)
for ann in annotations:
mask = self.coco.annToMask(ann)
mask_img = Image.fromarray((mask*255).astype(np.uint8))
qt_img = ImageQt.ImageQt(mask_img) # convert Image to ImageQt
icon = QtGui.QIcon(QtGui.QPixmap.fromImage(qt_img))
item = QtWidgets.QListWidgetItem(icon, f"{annIndex}")
self.listWidget.addItem(item)
annIndex += 1

EaselJS: Is there any way to export a shape to an image file?

I have a project in CreateJS which I'd like to remake without CreateJS, but it seems that all my images are in an EaselJS shape format. For example:
this.shape_1 = new cjs.Shape();
this.shape_1.graphics.f("#465762").s().p("AgOAOQgFgFAAgJQAAgHAFgHQAHgFAHgBQAIABAHAFQAFAHAAAHQAAAJgFAFQgHAHgIgBQgHABgHgHg");
this.shape_1.setTransform(43.4,42,0.747,0.747);
Is there some method I could use to export that to an image file?
You can export any EaselJS DisplayObject by caching it, and then exporting the dataURL. Note that you have to know the raw bounds. If you want a larger cache of it, just increase the scale parameter.
this.shape_1.cache(x, y, w, h, [scale]);
var url = this.shape_1.getCacheDataURL();
Unfortunately this method does not support the parameters of the Canvas.toDataURL(), so if you want that, you can hit the cache directly:
this.shape_1.target.cacheCanvas.toDataURL(…[type], [encoderOptions]);
Then, you can use the dataURL in a number of ways. Here is an article on it. Alternatively, just throw the generated cache into the DOM, and right-click on it to save.
document.body.appendChild(this.shape_1.target.cacheCanvas);
Docs:
DisplayObject.cache()
EaselJS getCacheDataURL()
Canvas.toDataURL()

Easeljs getBounds, when are dimensions set?

I'm importing someone's createjs application into an application loader which imports each developers application javascript to a global canvas. The application is working standalone but when I load the javascript dynamically I'm getting some strange behavior surrounding the getBounds() function.
I have some text created like this:
dialogText = new createjs.Text(text, 'bold ' + (28 * scale) + 'px Calibri', '#FFFFFF');
Then later on I use dialogText.getBounds() which returns null.
I try console logging dialogText and I can see that it is set and there is a value _bounds which reads null.
At what point do these values get set when the element in drawn to the canvas?
Note: I'm already adding the text to a createjs.Container() which has its bounds set before I run getBounds().
For a quick reference, I pasted EaselJS's update regarding getBounds():
(This dates back from "August 21, 2013", not sure if this is still necessary nowadays, but using setBounds(x, y, w, h) helped me with Shapes today [in 2017] actually!)
Source: http://blog.createjs.com/update-width-height-in-easeljs/
The _bounds property reflects a value that is manually set on the DisplayObject - which is helpful if you know the bounds of something that can't calculate it (like a Shape). It will always be null, unless you set it directly.
I tested your code, and it seems fine. Are you sure the scale or text values are not null? Maybe hard-code them to see if it works.
Do you have a sample somewhere? I noticed in the GitHub issue you posted that you mentioned it worked fine without RequireJS (though you don't mention that here). I would definitely ensure that the values are being set properly.
Here is the fiddle, as well as a simpler one with no EaselJS stage. Note that I have Calibri installed on my machine, so you might get different results if you are loading it in.
Sample code:
var dialogText = new createjs.Text("This is some text", 'bold ' + (28 * 1.5) + 'px Calibrix', '#FFFFFF');
console.log(">>",dialogText.getBounds());

How to create json rectangle data from a Photoshop script

I have a photoshop script that is cutting up layers of a PSD file into tiles (it's for a parallax game engine). This works well, but now I want to be able to create regions (rectangles) in the PSD that can be detected by the script and exported as json data.
Can anyone suggest a good way in Photoshop to a) visually create this information in the PSD and b) the script that would write out this data?
Any help would be greatly appreciated - this would remove about 3 manual, error prone steps from our current process if we can solve it...
If it's just rectangles that will hold the data for you then that's easy. You can just create a layer with a unique name, select the area that you need the data for, fill that with a single colour - say bright orange or something that will stand out. So now you have a layer with your region data. In your script get the layer by name
app.documents.getByName("Data_for_Region_1");
...and then you can then export that layer's data (co-ordinates - presumably) as a JSON file with layer bounds.
var x = parseFloat(app.activeDocument;.activeLayer.bounds[0])
var y = parseFloat(app.activeDocument;.activeLayer.bounds[1])
var x1 = parseFloat(app.activeDocument;.activeLayer.bounds[2])
var y1 = parseFloat(app.activeDocument;.activeLayer.bounds[3])
Hope this helps

GDAL appears to ignore NoDataValue

I'm trying to build a mosaic, and I rely on the NoDataValue feature to treat some parts of the image as transparent.
However, it appears that GDAL doesn't work as expected.
I also created a very simple test case using a vrt dataset and gdal_translate - and I get the same results (that is - the 2nd image draws over the 1st image, ignoring "transparent areas")
I have to 100X100 image files with a white marking (different in each file) over black background (black being exactly equal to 0)
I built a simple vrt file:
<VRTDataset rasterXSize="100" rasterYSize="100">
<VRTRasterBand dataType="Byte" band="1">
<ColorInterp>Gray</ColorInterp>
<SimpleSource>
<SourceFilename relativeToVRT="1">a1.tif</SourceFilename>
<SourceBand>1</SourceBand>
<SrcRect xOff="0" yOff="0" xSize="100" ySize="100"/>
<DstRect xOff="0" yOff="0" xSize="100" ySize="100"/>
<HideNoDataValue>1</HideNoDataValue>
<NoDataValue>0</NoDataValue>
</SimpleSource>
<SimpleSource>
<SourceFilename relativeToVRT="1">a2.tif</SourceFilename>
<SourceBand>1</SourceBand>
<SrcRect xOff="0" yOff="0" xSize="100" ySize="100"/>
<DstRect xOff="0" yOff="0" xSize="100" ySize="100"/>
<HideNoDataValue>1</HideNoDataValue>
<NoDataValue>0</NoDataValue>
</SimpleSource>
</VRTRasterBand>
</VRTDataset>
and I run the command:
gdal_translate mosaic.vrt mosaic.tif
The result is identical to image a2.tif, instead of being a combination of a1.tif and a2.tif
I got the error using gdal 1.8 and 1.9
any ideas?
I got an answer in the gdal-dev list from Even Rouault
Several errors :
The NoDataValue and HideNoDataValue elements are only valid under the VRTRasterBand element, not SimpleSource
You want to change SimpleSource to ComplexSource, and add a <NODATA>0</NODATA> element in it. (well basically rename your current NoDataValue to NODATA.