GIMP Python-fu exporting file only exports transparent layer - scripting

I am having issues saving images in python via GIMP. I can get the image and apply the effects I want, but when I go to save, it only saves one layer and not everything (NOTE: The background is transparent) and because the background is transparent, I cannot get it to save anything besides the transparent background. The code I am using is posted below:
image_array = gimp.image_list()
i=0
for image in image_array:
img = image_array[i]
layers = img.layers
last_layer = len(layers)-1
try:
disable=pdb.gimp_image_undo_disable(img)
pdb.gimp_layer_add_alpha(layers[0])
drw = pdb.gimp_image_active_drawable(img)
pdb.plug_in_colortoalpha(img,drw,(0,0,0))
drw = pdb.gimp_image_active_drawable(img)
enable = pdb.gimp_image_undo_enable(img)
except:
print "ERROR"
pdb.file_png_save(img, drw, "C:\\Users\\jammer\\Desktop\\test.png",
"test.png",0,9,1,1,1,1,1)
i+=1
I have also tried file_png_save2, but I have a feeling the problem lies in the drw object as I just want to replicate the option of clicking File->Export and saving as PNG without doing that via GUI. I would rather have it save automatically (I have 49 images and each will be named automatically, but first I need to get it to export correctly with one image). as I said before, the code above only exports a transparent background, even changing to a GIF does not resolve the issue. How do I export a file as a PNG while keeping all layers and transparent background?

I found my problem! I was not merging the visible layers and setting that equal to the new layer, which I then used as the "drawable object" when saving the image as a png! I have posted the fixed code below:
image_array = gimp.image_list()
i=0
for image in image_array:
img = image_array[i]
layers = img.layers
last_layer = len(layers)-1
try:
disable=pdb.gimp_image_undo_disable(img)
pdb.gimp_layer_add_alpha(layers[0])
drw = pdb.gimp_image_active_drawable(img)
pdb.plug_in_colortoalpha(img,drw,(0,0,0))
layer = pdb.gimp_image_merge_visible_layers(img, gimpfu.CLIP_TO_IMAGE)#FIXES PROBLEM OF ONLY EXPORTING TRANSPARENCY!
enable = pdb.gimp_image_undo_enable(img)
except:
print "ERROR"
pdb.file_png_save2(img, layer, "C:\\Users\\jammer\\Desktop\\test.png","test.png",1,9,1,1,1,1,1,0,1)
i+=1

Related

forcing square data matrix codes using ZXing.Net?

I was wondering if there was a way to ensure that a data matrix code created with ZXing.Net comes out as a square?
I'm not talking about the the image itself but the code itself.
I have code that generates images with data matrix codes from input texts and in some cases it is a square code (the code not the image) and in other cases it is more like a flat rectangle (the code, not the image).
So is the flat rectangular code just how the code looks due to the input or can it in fact be forced into a square?
You can try the following snippet:
var writer = new BarcodeWriter
{
Format = BarcodeFormat.DATA_MATRIX,
Options = new DatamatrixEncodingOptions
{
SymbolShape = SymbolShapeHint.FORCE_SQUARE
}
};
var image = writer.Write("<your content here>");

MigraDoc Rotate Image (vb.net)

I am trying to create a PDF using MigraDoc Library. I can add an image, but unable to rotate images. I am creating a MigraDoc.DocumentObjectModel.Shapes.Image object to add the image to a section. Is it possible to rotate the image or do I have to add the image another way?
Public Sub AddImageToPDFFile(sec As Section)
Dim image As Image
Dim strImagePath = "image.jpg"
image = sec.AddImage(strImagePath)
image.Height = "10cm"
image.LockAspectRatio = True
image.RelativeVertical = RelativeVertical.Line
image.RelativeHorizontal = RelativeHorizontal.Margin
image.Top = ShapePosition.Top
image.Left = ShapePosition.Left
image.WrapFormat.Style = WrapStyle.Through
End Sub
I'm afraid MigraDoc cannot rotate the image.
Maybe rotate the image with code before adding it to MigraDoc.
It might also be possible, depending on your requirements, to add the image later using PDFsharp. MigraDoc uses PDFsharp to create the PDF and thus you can use PDFsharp for modifications without adding an additional tool to the process.

PDFsharp Not Reading in Correct Page Size

I'm trying to develop an application to watermark PDF's. I'm having an issue with saving the PDF document in the correct format.
I've noticed that some documents when pulled in will read the page size as one thing but when I go to save the document part of it will be cut off. For example I have a document saved in landscape at 792x612 pts which correlates to a letter size. However when saved in letter it cuts part of the page off. I noticed that if I save the document in A1 that the entire document will then be present. Here is my code:
Dim gfx As XGraphics = XGraphics.FromPdfPage(page, XGraphicsPdfPageOptions.Append)
gfx.RotateTransform(-90)
Dim font As XFont = New XFont("Times New Romans", 6, XFontStyle.Bold)
Dim tf As XTextFormatter = New XTextFormatter(gfx)
Dim rect As XRect = New XRect(-550, 500, 250, 150)
gfx.DrawRectangle(XBrushes.Transparent, rect)
tf.DrawString(Text, font, XBrushes.Red, rect)
page.Size = PdfSharp.PageSize.A1
page.Orientation = PdfSharp.PageOrientation.Landscape
Doc.save(strFileSaveLocation)
Is there any reason why this could be happening? I am reading the page.height and page.width and confirming these to be correct before continuing.
There is a known bug in PDFsharp when it comes to handling pages in landscape format. This bug is present up to PDFsharp 1.50 beta 3b, but should be fixed with the next release.
See discussion in the PDFsharp forum:
http://forum.pdfsharp.net/viewtopic.php?p=9591#p9591
Suggested fix in PdfPage.cs:
internal PdfPage(PdfDictionary dict)
: base(dict)
{
// Set Orientation depending on /Rotate.
//int rotate = Elements.GetInteger(InheritablePageKeys.Rotate);
//if (Math.Abs((rotate / 90)) % 2 == 1)
// _orientation = PageOrientation.Landscape;
}
If you do not want to modify PDFsharp, maybe try the workaround from the first post:
http://forum.pdfsharp.net/viewtopic.php?p=9587#p9587
For others running into the same issue as me, the answer is to simply set the orientation to portrait. This for some reason will trigger the document to save correctly. The answer by PDFsharp Novice will allow you to fix your code to some extent, but if you're like me and need to know the orientation in order to process the page the solution is setting the orientation back to portrait. You may need to reset page width and height also.
Code:
page.Orientation = PdfSharp.PageOrientation.Portrait
page.Width = dblPageWidth
page.Height = dblPageHeight

Add flat amount to canvas size

I want to have some automated process (either action or script) that will copy selection(assumes something has already been selected), place in new canvas, increase canvas size by exactly 10 pixels in height & width, then save it to the desktop.
I'm currently using an action and it works correctly with the exception of the 10 pixels part. I can do something like 10% by using the percentage adjustment in the canvas size menu, but I can't figure out how to do exactly 10 pixels. During the recording, if I just increase the canvas size by 10 pixels it'll record that exact amount (say it was 100x100, it records that I resized canvas to 110x100). So when I play that action on a selection that's of size 50x50 it resizes it to 110x110.... So the problem is that the action records the literal value of the canvas resize and not the add 10 pixels part...
Any ideas here?
This can be scripted as well, but if you've already got an action set up, try modifying your action to do the following:
paste the selection into new document larger than you expect to ever require
expand the selection by 10 px
crop the document to the selection
save
Or, to script it you can tweak the following sample. It assumes you have already copied your image to the clipboard:
#target photoshop
app.preferences.rulerUnits = Units.PIXELS;
app.preferences.typeUnits = TypeUnits.PIXELS;
var doc = app.documents.add('1000px');
var lyr = doc.artLayers.add();
doc.activeLayer = lyr;
doc.paste ();
var bnds = lyr.bounds;
var unitsToAdd = new UnitValue(10, 'px');
bnds[0] = bnds[0] - unitsToAdd;
bnds[1] = bnds[1] - unitsToAdd;
bnds[2] = bnds[2] + unitsToAdd;
bnds[3] = bnds[3] + unitsToAdd;
doc.crop(bnds) ;
doc.saveAs(new File('/c/temp/temp.psd'));

react on events generated by chaco tools: how to get values out of a chaco tool when an event is fired ?

actually this should be a pretty simple question, but I am experiencing the quite steep learning curve of chaco and traits...
I am currently writing an application to plot a medical image using chaco and traits and I simply want to pick a pixel location from the image and use this pixel location to do evaluations on an image stack. So I started to write my own Chaco Tool that reacts on mouse clicks on an imageplot.
This works fine so far. When I click on the imageplot I can see the mouse coordinates WITHIN the Tool (a custom made PixelPickerTool). However, as I want to use this coordinate value outside the tool my question would be: How can I hand the coordinates over to another object or variable OUTSIDE the Tool when an event is fired.
To illustrate what I want to do I attached the main structure of the two classes I am Writing:
class PixelPickerTool(BaseTool):
'''Pick a Pixel coordinate from an image'''
ImageCoordinates = [0,0]
def normal_left_down(self, event):
print "Mouse:", event.x, event.y,
click_x, click_y = self.component.map_data((event.x, event.y))
img_x = int(click_x)
img_y = int(click_y)
coord = [img_x, img_y]
if ( (img_x > self.ImageSizeX) or (img_x < 0) ):
coord = [0,0]
if ( (img_y > self.ImageSizeY) or (img_y < 0) ):
coord = [0,0]
print coord
# this print gives out the coordinates of the pixel that was clicked - this works fine...
# so inside the picker too I can get the coordinates
# but how can I use the coordinates outside this tool ?
class ImagePlot(HasTraits):
# create simple chaco plot of 2D numpy image array, with a simple interactor (PixelPickerTool)
plot = Instance(Plot)
string = String("hallo")
picker = Instance(PixelPickerTool)
traits_view = View(
Item('plot', editor=ComponentEditor(), show_label=False,width=500, height=500, resizable=False),
Item('string', show_label=False, springy=True, width=300, height=20, resizable=False),
title="")
def __init__(self, numpyImage):
super(ImagePlot, self).__init__()
npImage = np.flipud(np.transpose(numpyImage))
plotdata = ArrayPlotData(imagedata = npImage)
plot = Plot(plotdata)
plot.img_plot("imagedata", colormap=gray)
self.plot = plot
# Bild Nullpunkt ist oben links!
self.plot.default_origin = 'top left'
pixelPicker = PixelPickerTool(plot)
self.picker = pixelPicker
plot.tools.append(pixelPicker)
I want to use the coordinates that are measured by the PixelPickerTool somewhere in this ImagePlot class. E.g. by handing them over to another Object like MyImageSeries.setCoordinate(xy_coordinateFromPickerTool)
So how can I hand over the pixel coordinates from PickerTool to some member variable in this class when an event is fired ?
Maybe something like this: self.PixelCoordinates = picker.getPixelCoordinates() could work ?
But how do I know then, when the on_normal_left_down function was executed in the picker ?
In the end I want to hand the coordinates over to another class which hold more images to process the images and do a fit at the pixel position determined in the ImagePlot.
I tried to use something like "_picker_changed" in my imagePlot class to detect if an event has been fired in the PickerTool, but this didn't detect event firing. So maybe I am doing something wrong...
Can anybody tell me how to get events and associated variables out of this picker tool ?
Cheers,
Andre
"But how do I know then, when the on_normal_left_down function was executed in the picker?"
There are several ways you could probably do this, but one way would be to simply do exactly what you are asking and fire an event that you define explicitly.
for instance:
from traits.api import Event
class PickerTool(BaseTool):
last_coords = SomeTrait
i_fired = Event
def normal_left_down(self,event):
# do whatever necessary processing
self.last_coords = do_some_stuff(event.some_attribute)
# now notify your parent
self.i_fired = True
and then listen to plot.picker.i_fired from wherever you want to display, and look in plot.picker.last_coords for the saved state.
Another thing you can do that may be simpler if what you want to do with these coordinates is very straightforward, is just pass on intialization the data structures the picker needs to interact with (or get them with a chain of calls to self.parent) and do your work directly inside the picker.