#!/opt/bin/perl use Gimp; use Gimp::Fu; use Gimp::UI; # Dieses Plugin ist etwas ganz Besonderes: Es speichert Bilder # im mehr-oder-weniger sinnvollen COLORHTML-Format. Kein Wunder # also, daß es das Fcntl-Modul (File-Control) benötigt. use Fcntl; # Nun, wer kennt es nicht... & wird in HTML zu &, < zu < und # (damit es symmetrisch ist) > zu > my %replace = ( "&" => "&", "<" => "<", ">" => ">", ); register "file_colorhtml_save", "Saves the image as coloured html text", "=pod", "Marc Lehmann", "Marc Lehmann ", "1999-11-22", "/COLORHTML", # Wir gehören in den -Dialog. "*", [ # Endlich einmal ein Plugin mit vielen Parametern, mit # denen man diverse Varianten der Ausgabe steuern kann: [PF_RADIO, "character_source", "where to take the characters from", 0, [sourcecode => 0, textfile => 1, filename => 2]], [PF_FILE, "characters", "the filename to read or the characters to use", ""], [PF_STRING, "font_size", "the html font size (1..7 or -7 .. +7)", 2], [PF_BOOL, "compatible", "html-4.0 compliancy?", 1], [PF_BOOL, "closetag", "add closing tag?", 1], ], sub { my($img,$drawable,$filename,$filename2,$source,$text,$size,$html40,$closetag) = @_; my($new_img,$new_drawable); my $max; # Nahezu jedes Datei-Speichern-Plugin ruft zuerst die export_image-Methode # auf. Sie wandelt ein Bild temporär in das vom Plugin benötigte Format. # Dadurch kann das Plugin in dem Format arbeiten, das es benötigt, und der # Benutzer in dem Format, das er bevorzugt: my $export = Gimp::UI::export_image ($new_img=$img, $new_drawable=$drawable, "COLORHTML", EXPORT_CAN_HANDLE_RGB); die __"export failed" if $export == EXPORT_CANCEL; my ($w,$h) = ($new_drawable->width, $new_drawable->height); Gimp->tile_cache_ntiles($w / Gimp->tile_width + 1); # Ein Speichern-Plugin erzeugt eine Datei... dies geschieht hier: sysopen FILE, $filename, O_CREAT | O_TRUNC | O_WRONLY or die __"Unable to open '$filename' for writing: $!\n"; # Je nach Auswahl der Quelle (Quellcode des Plugins, Datei oder String) # wird die Variable $data mit den Buchstaben gefüllt, die die "Pixel" # des Bildes ausmachen. my $data; if ($source == 0) { seek DATA, 0, 0; $data = do { local $/; }; } elsif ($source == 1) { local *FILE; open FILE, "<$text" or die "$text: $!\n"; $data = do { local $/; }; } elsif ($source == 2) { $data = $text; } # Nur damit wir auch ganz auf der sicheren Seite sind, werden # Leerzeichen und andere "suspekte" Zeichen entfernt. my @data; $data =~ y/\x21-\x7f//cd; @data = split //, $data; # Und schließlich werden gefährliche HTML-Zeichen durch Entities # ersetzt. for (@data) { s/([&<>])/$replace{$1}/e; } # Und falls nix übrigbleibt, nehmen wir viele Xe. @data = ("X") x 80 unless @data; my @chars; # Um auf die Pixeldaten zuzugreifen, wird eine Pixelregion erzeugt my $region = $new_drawable->pixel_rgn (0, 0, $w, $h, 0, 0); # Eine Fortschrittsanzeige stört auch nicht. init Progress __"Saving '$filename' as COLORHTML..."; $closetag = $closetag ? "" : ""; print FILE "\n
\n";

   # Diese Schleife geht durch alle Zeilen des Bildes, liest sie aus
   # und erzeugt HTML:
   for (my $y = 0; $y < $h; $y++) {
      # get_row2 liefert die Pixeldaten als Byte-String.
      my $pel = $region->get_row2 (0, $y, $w);

      # Sorge dafür, daß @chars mindestens so lang wie das Bild breit ist.
      push @chars, @data while @chars < $w;

      if ($html40) {
         # Soll das Ganze HTML4-kompatibel sein, muß etwas mehr ausgegeben
         # werden.
         # In dieser Regex werden jeweils Drei-Byte-Gruppen (ein Pixel)
         # durch ein -Element mit einem color-Attribut der Pixelwerte
         # in Hexadezimal (z.B. #1233c0) ersetzt und einem einzelnen Zeichen
         # aus @chars als Inhalt.
         $pel =~ s{(...)}{
            "".shift(@chars).$closetag;
         }ges;
      } else {
         # Bei nicht so ganz korrektem HTML kann etwas gespart werden.
         $pel =~ s{(...)}{
            "".shift(@chars).$closetag;
         }ges;
      }
      
      # Macht manche Editoren glücklicher.
      print FILE $pel,"\n";

      update Progress $y/$h;
   }
   print FILE "
\n\n"; # Falls die export_image-Funktion eine Kopie des Bildes erzeugen mußte, # zerstöre diese nun. $new_img->delete if $export == EXPORT_EXPORT; (); }; # "register" registriert lediglich eine Funktion. Damit Gimp auch weiß, # daß diese Funktion zum Speichern von Dateien dient, muß sie nochmals # mit register_save_handler als solche registriert werden. Dabei kann man # gleich eine Dateiendung angeben. Gimp::on_query { Gimp->register_save_handler("file_colorhtml_save", "colorhtml", ""); }; exit main; # Und wie jedes ordentliche Gimp-Plugin enthält auch dieses eine # ausführliche Hilfe. =head1 COLORHTML FILE FORMAT This file save filter writes a large regular grid filled with coloured characters. The characters can be stored in file and don't have anything to do with the image. The colour of each character, though, is taken from the image to save. This creates some kind of mosaic effect with characters. The pictures should be limited to about 120x120 pixels, since most browsers do not view larger images. The aspect ratio depends on the fixed-width font the browser is using, and is usually around 2:1 (so you should squash your image accordingly). The FONT tags can be saved either HTML-4.0 compliant (C) or in a proprietary format most browsers support (C). To save even more space you can leave out the closing tag (C), but this will potentially leave thousands of font elements open in the browser, and will disturb the current font colour. =cut __END__