#!/usr/bin/perl use strict; use SWF::File; use SWF::Element; use Image::Magick; use Compress::Zlib; use Getopt::Std; my %opt; getopts('ft', \%opt); my ($imagefile, $swffile) = @ARGV; unless (defined $imagefile) { print STDERR <new; $image->Read($imagefile); my $height = $image->Get('height'); my $width = $image->Get('width'); die "Can't open $imagefile." if ($height == 0 and $width == 0); my ($lossless, $tp); if ($opt{t} and $image->Get('matte')) { $lossless = SWF::Element::Tag::DefineBitsLossless2->new; $tp=1; } else { $lossless = SWF::Element::Tag::DefineBitsLossless->new; $tp=0; } $lossless->configure ( CharacterID => 1, BitmapWidth => $width, BitmapHeight => $height, ); if ((my $colors = $image->Get('colors'))>=256 or $opt{f}) { $lossless->BitmapFormat(5); # fullcolor my $d = deflateInit() or die "Can't open zlib stream."; for(my $y = 0; $y<$height; $y++) { for(my $x = 0; $x<$width; $x++) { my @rgba = split /,/, $image->Get("pixel[$x,$y]"); if (!$tp) { pop @rgba; unshift @rgba, 0; } else { $rgba[3] = 255-$rgba[3]; @rgba=@rgba[3,0..2]; } my ($output, $status) = $d->deflate(pack('CCCC',@rgba)); # 4 bytes per pixel. die "Compress error." unless $status == Z_OK; $lossless->ZlibBitmapData->add($output); } } my ($output, $status) = $d->flush(); die "Compress error." unless $status == Z_OK; $lossless->ZlibBitmapData->add($output); } else { $lossless->BitmapFormat(3); # bitmap with colormap $lossless->BitmapColorTableSize($colors-1); my (%colors, $pixels); my $index = 0; my $pad = "\x00" x (4 - $width % 4); my $d = deflateInit() or die "Can't open zlib stream."; for(my $y = 0; $y<$height; $y++) { for(my $x = 0; $x<$width; $x++) { my $rgba; unless (exists $colors{$rgba = $image->Get("pixel[$x,$y]")}) { $colors{$rgba} = pack('C',$index++); } $pixels .= $colors{$rgba}; } $pixels .= $pad; } %colors = reverse %colors; $tp = $tp ? 'CCCC':'CCC'; for my $k (sort keys %colors) { my @rgba = split /,/, $colors{$k}; $rgba[3] = 255-$rgba[3]; my ($output, $status) = $d->deflate(pack($tp, @rgba)); die "Compress error." unless $status == Z_OK; $lossless->ZlibBitmapData->add($output); } my ($output, $status) = $d->deflate($pixels); die "Compress error." unless $status == Z_OK; $lossless->ZlibBitmapData->add($output); ($output, $status) = $d->flush(); die "Compress error." unless $status == Z_OK; $lossless->ZlibBitmapData->add($output); } # create SWF. my $swf = SWF::File->new($swffile); $swf->FrameRate(15); $swf->FrameSize(0,0,$width*20,$height*20); # It can't set the same size??? SWF::Element::Tag::SetBackgroundColor->new( BackgroundColor => [ Red => 128, Green => 255, Blue => 255, ], )->pack($swf); # lossless tag is packed here. $lossless->pack($swf); # define the same size rectangle filled with the bitmap. SWF::Element::Tag::DefineShape2->new( ShapeID => 2, ShapeBounds => [ Xmin => 0, Ymin => 0, Xmax => $width, Ymax => $height ], Shapes => [ FillStyles => [ FillStyleType => 0x40, BitmapID => 1, ], ShapeRecords => [ [MoveDeltaX => 0, MoveDeltaY => 0, FillStyle0 => 1], [DeltaX => $width], [DeltaY => $height], [DeltaX => -$width], [DeltaY => -$height] ], ], )->pack($swf); SWF::Element::Tag::PlaceObject2->new( CharacterID => 2, Depth => 1, Matrix => [ TranslateX => 0, TranslateY => 0, ScaleX => 20, ScaleY => 20, ], )->pack($swf); my $sf = SWF::Element::Tag::ShowFrame->new; $sf->pack($swf); SWF::Element::Tag::DoAction->new( Actions => [[Tag => 'ActionStop']], )->pack($swf); $sf->pack($swf); SWF::Element::Tag::End->new->pack($swf); $swf->close;