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;