script for extracting embedded jpeg images
The following is a Perl script I wrote for extracting jpeg images that are embedded in an SVG file. I thought it might be useful to some other people. Adobe Illustrator writes SVG output with jpeg images embedded in it.
Please correct me if I'm wrong, but AFAICT Inkscape handles <image> tags just fine if they link to an external jpg, but doesn't handle the case where the jpg is embedded.
======
#!/usr/bin/perl
# usage: # extract_jpg_from_svg foo.svg # extracts an embedded jpg to foo.emb.jpg (or foo.emb1.jpg, foo.emb2.jpg, ... # if there is more than one)
# SVG files generated by AI may have JPEG images embedded in them that look sorta like # this: # <image width="554" height="412" id="XMLID_13_" xlink:href="data:;base64,/9... # The /9 is guaranteed to be there because the magic number of a JPEG file is ffd8 at # a zero offset into the file.
use strict;
use MIME::Base64;
undef $/; # slurp whole file
my $svg = $ARGV[0];
die "input file $svg not found" if ! -e $svg; die "input file $svg not readable" if ! -r $svg;
open(FILE,"<$svg") or die "error opening file $svg for input, $!";
my $data = <FILE>;
my @jpg; my $n = 0; while ($data=~m/<image\s+(\w+="[^"]*"\s+)*xlink:href="data:;base64,(([0-9a-zA-Z+/]|\s)+=+)/g) { my $base64 = $2; if ($base64=~m@/9@) { my $binary = decode_base64($base64); if ($binary=~m/^\x{ff}\x{d8}/) { push @jpg,$binary; ++$n; } } }
if ($n==0) { print "no embedded jpgs found in file $svg\n"; } else { for (my $i=1; $i<=$n; $i++) { my $jpg_file = $svg; $jpg_file =~ s/.svg$//; $jpg_file = $jpg_file . '.emb'; if ($n>1) {$jpg_file = $jpg_file . $i}; $jpg_file = $jpg_file . '.jpg'; print "writing $jpg_file\n"; open(JPG,">$jpg_file") or die "error opening file $jpg_file for output, $!"; print JPG $jpg[$i-1]; close JPG; } }
close FILE;
Please correct me if I'm wrong, but AFAICT Inkscape handles <image> tags just fine if they link to an external jpg, but doesn't handle the case where the jpg is embedded.
No, since relatively recently we can handle embedded images. See share/examples/data_uri.svg for a demonstration.
However, your script can still be very useful. It would be wonderful if you could also create a reverse script that embeds an images references from an SVG into it using data: URIs. Then we would hook these scripts up as extensions to the Extensions menu (which we will hopefully have soon).
participants (2)
-
Ben Crowell
-
bulia byak