Converting SVG to PNG not working.


M

Mart van de Wege

Hi,

I'm trying to convert some graphs generated by SVG::TT::Graph to PNG,
using Image::Magick. However, I'm getting empty .png files back,
instead of PNG images.

This is the code I am using:


sub output {
my $self = shift;
my $outdir = $self->{OutDir};
die "No output directory set." unless $self->{OutDir};
my $tempdir = tempdir;
foreach my $graph( keys %{$self->{Graphs}} ) {
my $svg = $self->{Graphs}->{$graph};
print "converting $graph, using tempdir $tempdir\n";
open(my $fh,">","$tempdir/$graph.svg") or die "$!";
print $fh $svg;
close $fh;
open(FH,"<","$tempdir/$graph.svg") or die "$!";
my $image = Image::Magick->new(magick => 'svg');
$image->Read( file => \*FH );
close FH;
my $out_filename = "$graph.png";
chdir $outdir;
open(IMG_FILE,">","$graph.png") or die "$!";
$image->Write( { file => \*IMG_FILE,
filename => "$graph.png",
magick => 'png' });
close IMG_FILE;
}
}

(Note, I am using bareword filehandles because I thought it might make a
difference with an older module like Image::Magick. It doesn't work with
lexical handles either.)

A separate script that takes just a filename from the command line works
just fine:

#!/usr/bin/perl

use warnings;
use strict;

use Image::Magick;

my $infile=shift;

my ($basename,$filetype)=split(/\./,$infile);

open(INFILE,"<",$infile) or die "$!";

my $image=Image::Magick->new;
$image->Read(file=>\*INFILE);
$image->Set(density=>'300x300');
my $outfile=$basename . ".png";
open(OUTFILE,">",$outfile);
$image->Write(file=>\*OUTFILE, filename=>$outfile);

close(INFILE);
close(OUTFILE);

What is the difference I am overlooking here? Or should I just switch to
Image::LibRSVG?

Mart
 
Ad

Advertisements

S

sln

Hi,

I'm trying to convert some graphs generated by SVG::TT::Graph to PNG,
using Image::Magick. However, I'm getting empty .png files back,
instead of PNG images.

This is the code I am using:


sub output {
my $self = shift;
my $outdir = $self->{OutDir};
die "No output directory set." unless $self->{OutDir};
my $tempdir = tempdir;
foreach my $graph( keys %{$self->{Graphs}} ) {
my $svg = $self->{Graphs}->{$graph};
print "converting $graph, using tempdir $tempdir\n";
open(my $fh,">","$tempdir/$graph.svg") or die "$!";
^^^
I would try binmode($fh) here.
And examine the svg file.
print $fh $svg;
close $fh;

Otherwise for a test, starting here, hardcode a
known svg file and do the conversion to png
like you did with the script below.
open(FH,"<","$tempdir/$graph.svg") or die "$!";
my $image = Image::Magick->new(magick => 'svg');
^^
sets the object type?
The one Read file example doesen't set the object type
when reading from a filehandle, nor does it put it into binmode FH.
Try what works from the script below, change one thing at a time after
it starts working.
$image->Read( file => \*FH );
^^
check return value
And its funny Read() does not allow the exact same
parameters available to setAttribute. Write, new, etc..
all have them available.
close FH;
my $out_filename = "$graph.png";
chdir $outdir;
open(IMG_FILE,">","$graph.png") or die "$!";
$image->Write( { file => \*IMG_FILE,
^^
check return value
filename => "$graph.png",
magick => 'png' });
^^
This is suspicious here, is magick setting the
object attribute, or a help so that the module will
know what output type you really mean, just incase
it doesen't know how to parse filename => "$graph.png"
close IMG_FILE;

For the test, return from the sub here.
}
}

(Note, I am using bareword filehandles because I thought it might make a
difference with an older module like Image::Magick. It doesn't work with
lexical handles either.)

A separate script that takes just a filename from the command line works
just fine:

#!/usr/bin/perl

use warnings;
use strict;

use Image::Magick;

my $infile=shift;

my ($basename,$filetype)=split(/\./,$infile);

open(INFILE,"<",$infile) or die "$!";

my $image=Image::Magick->new;
$image->Read(file=>\*INFILE);
$image->Set(density=>'300x300');
my $outfile=$basename . ".png";
open(OUTFILE,">",$outfile);
$image->Write(file=>\*OUTFILE, filename=>$outfile);

close(INFILE);
close(OUTFILE);

What is the difference I am overlooking here? Or should I just switch to
Image::LibRSVG?

Mart

Good luck.
-sln
 
M

Mart van de Wege

^^^
I would try binmode($fh) here.
And examine the svg file.
The SVG files are fine. Note that I don't pass the { CLEANUP => 1 }
option to tempdir, so I can examine the intermediate output.
Otherwise for a test, starting here, hardcode a
known svg file and do the conversion to png
like you did with the script below.

^^
sets the object type?
The one Read file example doesen't set the object type
when reading from a filehandle, nor does it put it into binmode FH.
Try what works from the script below, change one thing at a time after
it starts working.

Actually, I tried it without setting magick. Didn't work either.

However, I'll try and take your suggestions into account and hack on the
script some more, adding some debugging print statements.

Mart
 
Ad

Advertisements

M

Mart van de Wege

David Harmon said:
On Sun, 18 Oct 2009 15:49:48 +0200 in comp.lang.perl.misc, Mart van de


Start with something simple

use Image::Magick;
my $img = Image::Magick->new;
my $x = $img->Read("20080428.gif");
die "$x" if $x;
$x = $img->Write("x.png");
die "$x" if $x;

Well, I broke out the conversion from the main loop, just dumped all the
svg files in one dir, and then ran a loop over those files to convert
them.

That appears to work just fine. I'll see if I can find what went wrong
at first, but for now I can continue working on my module.

Mart
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top