[magick-users] having a problem with rotation (transparent bg) after upgrade

Stas Bekman stas at stason.org
Tue Nov 27 16:47:04 PST 2007


Anthony Thyssen wrote:
> Stas Bekman on  wrote...
> | Anthony Thyssen wrote:
> | > Stas Bekman on  wrote...
> | > | Hi,
> | > |
> | > | ImageMagick used to make a smooth image rotation before. Now I've
> | > | upgraded to the latest version 6.3.7 (same issue with 6.3.2), and now
> | > | the rotation leaves a jiggy outline
> | > |
> | > | Here is the input file:
> | > |
> | > | in.jpg
> | > | http://img2.freeimagehosting.net/image.php?b7174eb966.jpg
> | > |
> | > | I run:
> | > | convert -rotate 5 -background "transparent" in.jpg out.jpg
> | > |
> | > | here is the output:
> | > | http://img2.freeimagehosting.net/image.php?007de57566.jpg
> | > |
> | > | can you see the border being all messed up now?
> | > |
> | > Try ordering the arguments right...
> | > Also make sure the image has a alpha channel
> | >
> | >    convert in.jpg -matte -background "transparent" -rotate 5 out.jpg
> | >
> | > | I need to use transparent background since the image is going to be
> | > | composited on top of other images.
> | > |
> | > | Is there some extra argument that I need to add now? (which I'd imagine
> | > | used to be added by default in the past, but it's no longer the case)
> | > |
> | > See IM examples, Image rotation.
> | >   http://imagemagick.org/Usage/distorts/#rotate
> |
> | I tried all the examples, Anthony. It's not working. It used to work
> | just fine before. I haven't touched my code, it just broke after the
> | upgrade to the latest IM :(
> |
> | I even tried:
> |
> | convert in.jpg -interpolate mesh -filter point -matte -background
> | "transparent" -virtual-pixel transparent +distort SRT 5 out.jpg
> |
> Sorry.  (Smack hand onto forehead)....
> 
> You saved the image into JPEG!!!!!
> Jpeg can not handle a transparent color!!!!!!
> 
> Save it to PNG (still include the -matte operator) and all should be
> well.
> 
>    convert in.jpg -matte -background "transparent" -rotate 5 out.png
> 
> If you need it as JPEG, you will have to flatten it onto a
> appropriate colored background, before hand.
> 
>   convert in.jpg -matte -background none -rotate 5 \
>           -background gray -flatten out.jpg
> 
> Or 'underlaying' a checkerboard background...
> 
>   convert in.jpg -matte -background none -rotate 5 \
>           -size 300x300 pattern:checkerboard -compose dstover -flatten \
>           out.jpg
> 
> PS:  the color 'none' is the same as 'transparent'

Thank you very much, Anthony.

The key was -flatten. It used to work before with jpeg output w/o 
flatten. Now I added:

$background->Set(background   => "black");
$background = $background->Flatten();

and it's smooth border after rotation again!!! Yeah!

$background is the image on which I composite a bunch of icons in 
rotated form, which results in stacks as following:
http://stason.org/photos/gallery/place/index.html

Here is the function I use to create this kind of stacked images (in perl)

sub make_img_stack_flat {
     my ($imgs, $output) = @_;

     my @imgs = @$imgs;

     my $background = Image::Magick->new;

     my $tw = 164;    # thumb width
     my $th = 285;    # sheared thumb hight
     my $w  = 800;    # stack image width
     my $h  = $th+28; # stack image height
     my $nw = $w - $tw;

     my $rc;

     $background->Set(size => "${w}x$h");
     $rc = $background->Read("xc:#00000000'");
     $background->Set(background   => "black");
     #warn "$rc" unless ref $rc;

     # use at most 25 images
     my $total = scalar @imgs;
     my $max = 25;
     $max = $total if $max > $total;
     my @rand = map { splice @imgs, int(rand $#imgs), 1 } 1..$max;
     # reverse, since otherwise the last image always ends up first if
     # there is less images than $max
     @imgs = reverse @rand;

     my $quotient = @imgs;
     my $unit = int ($nw / $quotient);

     #warn "quotient = $quotient, unit = $unit\n";

     #my $c = 2.6 + scalar @imgs;
     my $gap = $unit;
     my $c = 0;

     my @x = map { $nw - $unit*$_ } (1..$quotient);
     @x = map { splice @x, int(rand $#x), 1 } 1..$quotient;

     if ($quotient == 1) {
         @x = $nw - 140 - rand(1)*$nw/2;
     }

     for my $file (@imgs) {
         $c++;
         $gap += $unit;

         my $img = Image::Magick->new();
         $img->Read($file);

         # the bigger the number the closer the images are
         my $x = pop @x;
         my $y = 14 + rand(1)*70;

         $x = 14 if $x < 14; # don't run away

         #warn "$gap $x $y $file\n";

         # do something to the image
         my $err = $img->Rotate(
             degrees => 90*rand(1)-45,
             background   => "transparent",
         );
         die $err if $err;

         $img->Set(matte=>"true");
         $img->Set(background   => "transparent");
         $img->Set(interlace   => "PNG");

         my ($iw, $ih) = $img->Get('width', 'height');
         #warn "orig: $iw $ih $file\n";

# stopped working in imagemagick 6.3.2.x, but now seems to work
# without the 'compose' argument
#                               compose  => 'atop',

         my $err = $background->Composite(image    => $img,
                                x => $x,
                                y => $y,
         );
         die $err if $err;
     }

     $background = $background->Flatten();
     $background->Set(quality=>75);
     $background->Write($output);

}
-- 
_____________________________________________________________
Stas Bekman    mailto:stas at stason.org http://stasosphere.com/
http://www.linkedin.com/in/stasbekman http://stason.org/
http://stason.org/photos/gallery/     http://healingcloud.com
http://chestofbooks.com/              http://modperlbook.org/
                                       http://modperl2book.org



More information about the Magick-users mailing list