Perl Magick Resize Color Issue - perl

I'm writing a script to resize gif images. I've notice that the images I create have a smaller image size, but take up more room on disk. I think I've tracked down the cause of the problem. The original images when examined in photoshop only have 4 colors in their color table (white, gray, grayer, black) while the new images have 256 colors in their color table. I can't find a way to copy the color table from the incoming image, is there some way to control this? Here's my script
use Image::Magick;
my $image = Image::Magick->new;
$image -> Read( 'test.gif' );
$image -> Resize(geometry=>"50%");
$image->Write( 'test-out.gif' );
Any advice much appreciated.

You can use Sample() instead of Resize() to keep the same number of colours
$image->Sample(geometry=>"50%");

You can limit the number of output colors using the -colors option. It's a good idea to include the +dither option, even if you're sure you have the same number of colors in both input and output. In straight ImageMagick, it would look like this:
convert test.gif +dither -colors 4 test-out.gif
I don't know the syntax for the perlMagick API, but this should get you pretty close.

Related

Alter a person's race from the command line.

A disability project I'm building (here for your interest). Uses a set of copyright-free icons. Here are some examples of them in use.
It's bothering us that all of the icons are of white people. We'd like to make them more diverse and representative.
The icons are pngs. Here's an example. I feel like there must be a command line way of replacing one colour with another. If I had that, then I could do a lot of things semi-automatically, but I have NO idea if such a thing is possible.
Is it?
You can replace a specific color with another using ImageMagick or GraphicsMaqick. In your screenshot, the "flesh" is color #FFEFC6. Use -fill newcolor -opaque oldcolor to replace this color with another (and use "-fuzz 10%" to replace all pixels whose color is "close" to oldcolor):
magick pdzSe.png -fill black -fuzz 10% -opaque "#FFEFC6" black.png
magick pdzSe.png -fill orange -fuzz 10% -opaque "#FFEFC6" orange.png
magick pdzSe.png -fill brown -fuzz 10% -opaque "#FFEFC6" brown.png
If you want to use GraphicsMagick, replace magick with gm convert, and if you want to use ImageMagick version 6, replace magick with convert. If you're running on Windows, you'll need to replace the % with %%.
This should be enough to get you started, but it's a crude solution that doesn't account for blended pixels such as those appearing in your sample "thumbs-up" icon. Below are the results of running the same commands against "thumbs-up", enlarged 4x so you can see the "halo" effect around the edges of the "flesh". Getting rid of the "halos" will require more work, specific to your icon set. Ideally you'd have the original vector art-work to update, but I suppose that's not the case.
In fact, the original artwork is available at straight-street.com (search for "good") and working with the original SVG files is much simpler; there is no "halo" issue. Here I just used a text editor to change the color FFEFC6 to FF8888:

Libreoffice Draw Export Resolution makes no sense

I am attempting to make a very simple label using Libreoffice Draw v 4.0.2.2. The label has not much more to it than regularly spaced lines of centered text
This image will be printed, and I have a fixed size/ppi requirement to ensure appropriate print quality.
I set the page size to my specs, and layout the text as I desire. The print shop takes several image formats including .tiff and .png. When I export the image, a dialog pops up that asks for the image size/ resolution. The given ppi is very low (~40) and I require a minimum of 180ppi. When I enter this, the image size adjusts itself and results in an image that is far too small.
The only solution that appears to be viable is to explode the page size and the drawing text size so it gets shrunk upon export. This is a very imprecise and illogical feature (bug?) of the program that I really wish is a result of my ignorance.
I found a thread in the mailing list which describes this issue exactly. The only answer that is given is essentially "yes, this is ridiculous and doesn't help anybody".
Can anyone give some advice to this? Or at least shed some light on who might need this "feature"?
There is something off about the Export tool of LibreOffice in general. It has been years since it is broken. Taking a screenshot is an alternative, but obviously you cannot control the resolution.
So, a better work around is exporting to SVG, and then convert the SVG to PNG with Inkscape. Once downloaded, convert the file with the following command:
inkscape -z -e out.png -w 1024 in.svg
If you are in Windows (x64), you will need to indicate the full path:
"C:/Program Files/Inkscape/inkscape.exe" -z -e out.png -w 1024 in.svg
If you install the 32 bit version, this should work:
"C:\Program Files (x86)/Inkscape/inkscape.exe" -z -e out.png -w 1024 in.svg
This can be done from inside Libre Office, there is no need to use any external tool. The Export dialog is very confusing, yes; you have to realize that both size and resolution can be set independently.
Select File -> Export -> choose the desired format. The export dialog should appear.
TAKE NOTE of Width and Height. Set the desired resolution; notice how Width and Height change (?). Don't worry, restore Width and Height to your saved values. And that's it. You get a high resolution image with the desired size and DPI.
Libre Draw (the one I'm using anyway) is a vector drawing app - have you asked the print shop if they can use vector formats like eps, pdf? Most should be able to in my experience. Then resolution becomes irrelevant.
-Terry

Why does Perl's Image::Magick create an outline around a semi-transparent image but composite doesn't?

I'm working on a program to dynamically add watermarks to product images with Image::Magick. I'm using composite with the dissolve method. The watermark image is a PNG that has transparency. It's running on Linux with ImageMagick 6.7.6-9 2012-05-16 Q16.
Consider the following arbitrary example images:
Background (test.jpg):
Watermark/overlay (example.png):
If I put these together with the command line tool composite, everything is great.
composite -dissolve 60% -gravity center example.png test.jpg out.jpg
The text (this needs to be an image, there will be graphics in it, too) is superimposed over the background. The edges are just the way they were in the original watermark image.
#!/usr/bin/perl
use strict; use warnings;
use Image::Magick;
# this objects represents the background
my $background = Image::Magick->new;
$background ->ReadImage( 'test.jpg' );
# this objects represents the watermark
my $watermark = Image::Magick->new;
$watermark->ReadImage( 'example.png');
# there is some scaling going on here...
# both images are scaled down to have the same width
# but the problem occurs even if I turn the scaling off
# superimpose the watermark
$background->Composite(
image => $watermark,
compose => 'Dissolve',
opacity => '60%',
gravity => 'Center',
);
$background->Write( filename => 'out.jpg' );
Here's the output of this Perl program:
As you can see, the new image has some strange edges, almost like an outline. The larger this image gets (the original source images are both > 1000px) the more obvious this outline becomes.
Here's a closeup:
I believe it might have something to do with the strength of the JPEG compression because the wrong image has a lot more artefacts. But that would mean the defaults of Perl's Image::Magick and the CLI are different. I have not figured out how to set the compression yet.
Anyway, I'd be glad about any kind of input on why this might happen, or ideas and suggestions on how to get rid of it.
I had a quick look at the PerlMagick source code and it seems that Composite with Dissolve is buggy when the dissolved image has an alpha channel. The following works for me:
$watermark->Evaluate(
operator => 'Multiply',
value => 0.6,
channel => 'Alpha',
);
$background->Composite(
image => $watermark,
gravity => 'Center',
);

Setting Background Color in Perl Magick Image Conversion

I am using Perl Magick which is the Perl module for Image Magick to convert images from GIF and PNG to JPEG. Everything works perfectly until I try to convert an image with a transparent background.
The default behavior for the Resize() function is to use black which ruins the images we are trying to convert. I want to instead change the default background color to white and can't figure out how to do it.
If you use Image Magick on the command line you can change the background by using:
convert image.gif -background \#FFFFFF -flatten image.jpg
And here is the perl code I am using to resize and convert the image:
use Image::Magick;
my $image = Image::Magick->new();
$image->Read("input.png");
$image->Resize(geometry=>'500x');
$image->Write("output.jpg");
I tried the following to get it to work but to no avail:
use Image::Magick;
my $image = Image::Magick->new();
$image->Read("input.png");
$image->Set(background => 'white');
$image->Flatten();
$image->Resize(geometry=>'500x');
$image->Write("output.jpg");
And also:
use Image::Magick;
my $image = Image::Magick->new();
$image->Read("input.png");
$image->Resize(geometry=>'500x',background=>'white');
$image->Write("output.jpg");
I'd appreciate any help on figuring out how to set the default background color successfully for the Perl Magick Resize() method. Thanks in advance for your help!
I think the easiest way to convert transparent regions to white is to paste the image on top of a white background before resizing it:
use Image::Magick;
sub dims {
my ($image) = #_;
return $image->Get('width') . 'x' . $image->Get('height');
}
# First grab the image to be mangled.
my $image = Image::Magick->new();
$image->Read('input.png');
# Then, create a white image with the same size.
my $bg = Image::Magick->new(size => dims($image));
$bg->Read('xc:#ffffff');
# And overlay the original on top of it to fill the transparent pixels
# with white.
$bg->Composite(compose => 'Over', image => $image);
# Finally, continue on as normal using $bg instead of $image.
$bg->Resize(geometry => '500x');
$bg->Write('output.jpg');
I tested this with Graphics::Magick (a faster fork of ImageMagick) but it should work the same with Image::Magick.
I have tried to do similar image mangling in the past and the above was the best I could come up with.
Unfortunately I wasn't able to get this to work in a clean way that simply used the Resize() method and passed it an appropriate parameter to set the background color.
Instead what I've done to solve the problem is first convert the file to JPG format and then resize it afterwards. This works since the default background color for Image Magick is white so the background is set correctly during the conversion and then the Resize() method simply uses the JPG image without having to do any interpretation.
Not the ideal solution in my estimation but it does work reliably.
Did you try
$image->Flatten(background => 'white');

MATLAB: print pdf in black/white

Matlab prints figures in either black/white or color. A black/white print of a figure is NOT the same as a color print tweaked to black/white: every color including the light ones is translated as black. (Light colors that look good on screen or a color printer look horrible on a black/white printer)
I would like to print a PDF file of a figure. My problem is that there doesn't seem to be a PDF driver for MATLAB that outputs black/white rather than color.
See the print command: -dpdf is the PDF driver but it is color.
Is there any way I can do this?
(edit: http://www.mathworks.com/access/helpdesk/help/techdoc/creating_plots/f3-84337.html#f3-99776 shows the interactive way of doing this, but I need a programmatic method, otherwise it will get tedious rather quickly.)
You can fully automate the print process: http://UndocumentedMatlab.com/blog/customizing-print-setup/
You could convert it to an EPS (-deps or -deps2) and then use eps2pdf (which uses GhostScript) to convert that into a PDF. I generally convert all my figures to this way.