#!/usr/bin/perl # pcg@goof.com # this is not totally serious... use Gimp; use Gimp::Fu; use Gimp::UI; use Fcntl; sub encode_base64($) { my $res = substr pack ("u", $_[0]), 1; $res =~ s/\n.//mg; $res =~ tr|` -_|AA-Za-z0-9+/|; #` # syntax-hiliting in emacs kanns nicht my $padding = (3 - length($_[0]) % 3) % 3; $res =~ s/.{$padding}$/'=' x $padding/e if $padding; $res; } register "file_dataurl_save", "Saves the image as many small tiles using data:-urls", "=pod", "Marc Lehmann", "Marc Lehmann ", "1999-11-20", "/DATAURL", "*", [ [PF_SPINNER, "tile_x", "tile width", 32, [0, 8192, 1, 10]], [PF_SPINNER, "tile_y", "tile height", 32, [0, 8192, 1, 10]], [PF_RADIO, "filetype", "underlying file type", 0, [GIF => 0, JFIF => 1, PNG => 2]], ], sub { my($img,$drawable,$filename,$filename2,$tx,$ty,$type) = @_; my($new_img,$new_drawable); my $max; my $export = Gimp::UI::export_image ($new_img=$img, $new_drawable=$drawable, "DATAURL", $type==0 ? CAN_HANDLE_INDEXED|CAN_HANDLE_ALPHA : $type==1 ? CAN_HANDLE_RGB|CAN_HANDLE_GRAY : $type==2 ? CAN_HANDLE_RGB|CAN_HANDLE_GRAY|CAN_HANDLE_INDEXED : 0 ); die __"export failed" if $export == EXPORT_CANCEL; my ($w,$h) = ($new_drawable->width, $new_drawable->height); my $tmp = Gimp->temp_name(".img~"); sysopen FILE,$filename,O_CREAT|O_TRUNC|O_WRONLY or die __"Unable to open '$filename' for writing: $!\n"; print FILE "\n"; init Progress __"Saving '$filename' as DATAURL..."; my $media = $type==0 ? "gif" : $type==1 ? "jpeg" : $type==2 ? "png" : ""; print FILE ""; for(my $y=0; $y<$h; $y+=$ty) { my $wy = $h-$y < $ty ? $h-$y : $ty; print FILE ""; for(my $x=0; $x<$w; $x+=$tx) { my $wx = $w-$x < $tx ? $w-$x : $tx; my $img = $new_img->channel_ops_duplicate; $img->crop($wx,$wy,$x,$y); ($img->get_layers)[0]->file_gif_save (($tmp)x2, 0, 0, 0, 0) if $type==0; ($img->get_layers)[0]->file_jpeg_save (($tmp)x2, 0.7, 0, 1, 0, "", 0, 1, 0, 0) if $type==1; ($img->get_layers)[0]->file_png_save (($tmp)x2, 0, 1, 9) if $type==2; $img->delete; my $data = do { local(*TEMP,$/); open TEMP, "<$tmp" or die __"Unable to read temporary image tile $tmp: $!"; ; }; unlink $tmp; $url = "data:image/$media;base64,".(encode_base64 $data); $max = length($url) if length($url) > $max; print FILE "
"; update Progress (($y*$w+$x*$ty)/($w*$h)); } } print FILE "
\n"; print FILE "\n"; close FILE; warn __"url size is too large ($max > 1024)\n" if $max > 1024; $new_img->delete if $export == EXPORT_EXPORT; (); }; Gimp::on_query { Gimp->register_save_handler("file_dataurl_save", "dataurl", ""); }; exit main; =head1 DATAURL FILE FORMAT After reading rfc2397, which describes the C url scheme, I got the idea of embedding a normal image into a html document, without resorting to external files. This is acomplished by embedding small tiles of the image directly into data:-urls. Since attribute values are by default limited to 1024 bytes this limits the size of a tile to approximately 34x34 pixels (gif compression). However, since rfc2397 is only a proposed standard, you might want to use much larger tile sizes (upto the image size), since most browsers generally do not care for the url length. Browser compatibility list (send more results to pcg@goof.com ;) Netscape 4.x works in any setting Lynx displays the base64 code as text :( MSIE 4 thousands of error messages in dialog boxes ;-> MSIE 5 shows broken image icon