3

I'm trying to figure out how to use the Image::Resize Perl module, to scale down PNG images. The following code does work:

        my $image = Image::Resize->new($read_path);
        my $gd = $image->resize(1000,1000);
        open (DISPLAY,">$write_path") || die "Cant write $write_path, Reason: $!";
            binmode DISPLAY;
            if ($read_path =~ /\.jpg$/i) {           
             print DISPLAY  $gd->jpeg();
            } elsif ($read_path =~ /\.gif$/i) {           
             print DISPLAY  $gd->gif();
            } elsif ($read_path =~ /\.png$/i) {           
             print DISPLAY  $gd->png();
            }
        close DISPLAY;

However, the outcome isn't what I would like (the scaled version has a black background when you convert a transparent PNG)

Original: enter image description here

Scaled:

enter image description here

How can I tell it to put a white background on the image? I checked out the manpage, but couldn't see anything helpful:

http://search.cpan.org/dist/Image-Resize/Resize.pm

Thanks!

UPDATE: For anyone interested, what I ended up doing was just converting them from a .png to .jpg using convert;

convert "$read_path" -background white -flatten "$path/$filename"

That actually works out better in this instance, as we don't need the transparency (and jpg's are much smaller in size)

Andrew Newby
  • 4,941
  • 6
  • 40
  • 81
  • Since you get a [GD::Image](https://metacpan.org/pod/GD) back, you can use its method to inspect and alter things. Find out if the transparency is set correctly first, then how to make it render as white before you print it. – simbabque Aug 11 '16 at 09:10

2 Answers2

2

The Image::Resize module only does that, resizes the image.

However, it does return a GD::Image object. You can then use the full power of gd for your image.

The method GD::Image::transparent may be what you are looking for. Copied from docs

# allocate some colors
my $white = $im->colorAllocate(255,255,255);

# make the background transparent and interlaced
$im->transparent($white);
$im->interlaced('true');

The $im is a GD::Image object, in your case returned by Image::Resize::resize.

The particular problem isn't explained and I am not sure how you pick up the black background, but if the above doesn't do it you'll find the specific solution with the GD::Image.


This post may lead to a direct answer, by linking to this post : enable the saveAlpha() GD setting.

Thanks to Wick for the comment.

zdim
  • 64,580
  • 5
  • 52
  • 81
  • Thanks for the example. Are you suggesting something like: `my $image = Image::Resize->new($read_path); my $white = $image->colorAllocate(255,255,255); $image->transparent($white); $image->interlaced('true'); my $gd = $image->resize(1000,1000);` As that doesn't seem to work :( – Andrew Newby Aug 11 '16 at 09:18
  • @AndrewNewby Something like that, yes. I'd first resize then set the background. The problem is that your result clearly picks up the black background, somewhere else. This isn't about resizing. The asnwer to that is to use `GD::Image` -- you can certainly work it out with it (note that this is the `GD` module, the whole of it). I guess that you'll need to identify what sets it to black (and when). – zdim Aug 11 '16 at 09:23
  • Thanks. I ended up doing a bit of a dirty hack, by converting it from PNG into JPG using imagemagick: ``convert "$read_path" -background white -flatten "$path/$filename"`;`. TBH, thats probably the best option anyway - as JPG's are much smaller in filesize compared to PNG's – Andrew Newby Aug 11 '16 at 09:46
  • See https://stackoverflow.com/questions/4900766/how-to-preserve-transparency-when-resizing-png-using-perl-and-gd ... there's a saveAlpha() GD setting that needs to be enabled. – Wick Aug 16 '17 at 17:15
  • 1
    @AndrewNewby Note the above comment. I added a note to the end of my answer. – zdim Aug 16 '17 at 17:27
  • @Wick Thank you for the comment, added to my answer (and pinged the OP) – zdim Aug 16 '17 at 21:24
0

Oddly enough I ran across this same problem, again, 3 years later after commenting on the accepted answer about the saveAlpha() setting. This time I was working with source PNGs that only had an alpha transparency. Nothing with GD's saveAlpha() or transparent() settings worked when resizing & saving as JPGs. I got the dreaded black background each time.

What I did to fix it was create a new image, apply a white filled rectangle as a background, then apply the resized image on top of that:

my $width = 320;
my $height = 240;
my $image = GD::Image->new($width,$height);
my $white = $image->colorAllocate(255,255,255);
$image->filledRectangle(0,0,$width,$height,$white);
$image->saveAlpha(0);

my $gdo = GD::Image->newFromPng("filename.png");
$image->copyResampled($gdo,0,0,0,0,$width,$height,$gdo->width,$gdo->height);

open my $FH,'>',"filename.jpg";
binmode $FH;
print {$FH} $image->jpeg;
close $FH;
Wick
  • 1,222
  • 2
  • 15
  • 21