[Bioperl-l] bioperl graphics

Todd Harris todd.harris at cshl.edu
Mon Mar 1 10:43:37 EST 2004


> On 3/1/04 9:02 AM, Jonathan Crabtree wrote:

Hi Jason - 

Well, that's great news!  I couldn't remember if I had added colorResolve to
GD::SVG.  Whoops!  As you can see, it's something of a kludge, but I'm glad
to hear that it works for you.

Regarding Lincoln's suggestion of copying images, correct me if I'm wrong,
but I interpreted that to mean copying the images OUTSIDE of
Bio::Graphics::Panel.  That is, create your Panel, fetch it, then paste it
where appropriate into a new GD::Image with the appropriate dimensions. To
avoid the method-overriding aspects of GD::SVG, this might need to be done
within a separate package or eval block.

I'm planning a significant upgrade to GD::SVG over the next few weeks that
should 1) enable parallel creation of a GD object; 2) make it compatible
with more current GD methods, and 3) make it more robust for future methods.

t


> 
> Hi Lincoln-
> 
> Thanks for the quick response.  I thought there must have been a good
> reason for using colorAllocate(), but now I'm not sure that this is
> true.  I've been able to generate valid SVG documents using GD::SVG and
> a copy of Bio::Graphics::Panel modified in the way that I described to
> Haibo, so I don't think that my proposed change breaks SVG output
> outright.  I've been using GD-SVG-0.25, which already supports
> colorResolve().  Here are lines 292-297 of SVG.pm:
> 
> sub GD::SVG::Image::colorResolve {
> my ($self,$r,$g,$b) = @_;
> ###GD###my $index = $self->{gd}->colorResolve($r,$g,$b);
> my $index = $self->colorAllocate($r,$g,$b);
> return $index;
> }
> 
> I haven't looked at any past versions of GD::SVG, however, so perhaps
> this is a recent change.
> 
> I do like your suggestion about using multiple GD::Image objects and
> then copying the various Panel GD::Images into a single target
> GD::Image.  However, this approach definitely won't work with GD::SVG,
> which does not yet support any of the GD image copying methods (AFAIK,
> again based on the GD-SVG-0.25 code that I grabbed from CPAN.)  I'm not
> crazy about my current method, which involves manipulating pad_left,
> pad_top, etc., to arrange the various Bio::Graphics::Panels in their
> appropriate locations.  On the other hand, the API for
> Bio::Graphics::Panel does explicitly support the use of an
> externally-supplied GD::Image object when calling gd(), so I don't feel
> as though I'm abusing the module too much.  Using a single GD::Image (or
> SVG::GD::Image) also makes for a (marginally!) faster and more
> space-efficient solution.  Regards,
> 
> Jonathan
> 
> 
> Lincoln Stein wrote:
> 
>> -----BEGIN PGP SIGNED MESSAGE-----
>> Hash: SHA1
>> 
>> Sorry, but if you change colorAllocate() to colorResolve(), you will
>> break the ability to generate publication-quality images with
>> GD::SVG.  Perhaps Todd Harris will add colorResolve() to a future
>> version of GD::SVG, in which case I will make the suggested change to
>> Bio::Graphics.
>> 
>> I would recommend instead making two Bio::Graphics::Panel objects, and
>> generating a pair of GD objects (using the Panel->gd() method).  Then
>> you can combine them onto a third GD object in whatever geometry you
>> want by using GD->copy()
>> 
>> Lincoln
>> 
>> On Wednesday 25 February 2004 06:46 pm, Jonathan Crabtree wrote:
>>  
>> 
>>> Haibo-
>>> 
>>> hz5 at njit.edu wrote:
>>>    
>>> 
>>>> Is there any way to render 2 Bio::Graphics::Panel into one png
>>>> image? because I want 2 different arrows with different labeled
>>>> coordinates on the same image and align to the left, but one
>>>> Panel can only have one coordinates system.
>>>>      
>>>> 
>>> The answer is yes, with a couple of caveats.  The first is that you
>>> will have to take care of the layout of the individual
>>> Panel-generated images.  If you're left-justifying everything then
>>> this should be easy enough.  The second is that I would recommend
>>> making a one-line change to Bio/Graphics/Panel.pm, to prevent the
>>> package from trying to allocate the same set of colors twice (when
>>> you reuse the same GD object to draw the two different parts of the
>>> image.)  Search for the following piece of code in Panel.pm (at
>>> line 411 in bioperl-1.4, I think):
>>> 
>>>  for my $name ('white','black',keys %COLORS) {
>>>    my $idx = $gd->colorAllocate(@{$COLORS{$name}});
>>>    $translation_table{$name} = $idx;
>>>  }
>>> 
>>> Change "colorAllocate" to "colorResolve"; this should have no
>>> effect on any existing Bio::Graphics code (AFAIK) and will allow
>>> you to do your two (or three or four)-Panel trick.  (As an aside,
>>> I'd like to lobby for this one-line change to be made in a future
>>> version of
>>> Bio::Graphics::Panel, for precisely this reason.)  In any case,
>>> once you've made that change and reinstalled your copy of Bioperl,
>>> here is a rough outline of what you need to do:
>>> 
>>> 1. Set up your individual Bio::Graphics::Panel objects (e.g. $p1,
>>> $p2, $p3, etc.) as desired to draw your images, but do *not* call
>>> the gd method on any of them yet.
>>> 
>>> 2. Create a GD::Image object big enough to hold the images that
>>> will be drawn by $p1, $p2, $p3, etc.:
>>>    my $gdImg = GD::Image->new($fullWidth, $fullHeight);
>>> (Note: use $p1->width(), $p1->height(), etc., to determine what
>>> $fullWidth and $fullHeight should be, based on your desired Panel
>>> layout algorithm.)
>>> 
>>> 4. Use a "dummy" Bio::Graphics::Panel object to allocate all your
>>> colors (this is an optional step; I do this because my code does
>>> some drawing that isn't handled by Bio::Graphics::Panel, and want
>>> to make sure that the palette has been allocated before I start):
>>> 
>>>    my $dummyPanel = Bio::Graphics::Panel->new(-length => 100,
>>> -offset => 0, -width => $fullWidth);
>>>    $dummyPanel->gd($gdImg); # forces color allocation
>>> 
>>> 5. Draw the individual panels and generate your png image:
>>> 
>>>    $p1->gd($gdImg);
>>>    $p2->gd($gdImg);
>>>    my $pngData = $gdImg->png();
>>> 
>>> I've glossed over some of the details here, for example the fact
>>> that you may need to know the value of $p1->height() before you can
>>> initialize $p2, but that's the basic idea.  I've been using this
>>> method to generate some comparative sequence displays and while
>>> it's definitely a bit of a hack, it works well in practice.  You
>>> can also do the same thing with a GD::SVG::Image if you'd like to
>>> generate SVG output.  Good luck,
>>> 
>>> Jonathan
>>> 
>>> 
>>> 
>>> _______________________________________________
>>> Bioperl-l mailing list
>>> Bioperl-l at portal.open-bio.org
>>> http://portal.open-bio.org/mailman/listinfo/bioperl-l
>>>    
>>> 
>> 
>> - -- 
>> Lincoln D. Stein
>> Cold Spring Harbor Laboratory
>> 1 Bungtown Road
>> Cold Spring Harbor, NY 11724
>> -----BEGIN PGP SIGNATURE-----
>> Version: GnuPG v1.2.1 (GNU/Linux)
>> 
>> iD8DBQFAP1Zt0CIvUP7P+AkRAreyAJ0XIcjMDeT/Bw69OBOEhD8tsznP+QCfVLWo
>> +RnQaijXxPlVWTbmjTkbHYw=
>> =lN1U
>> -----END PGP SIGNATURE-----
>>  
>> 
> 
> 
> _______________________________________________
> Bioperl-l mailing list
> Bioperl-l at portal.open-bio.org
> http://portal.open-bio.org/mailman/listinfo/bioperl-l
> 



More information about the Bioperl-l mailing list