Discussion:
[Dvipng] accessing alpha channel
John Hunter
2005-05-18 14:32:37 UTC
Permalink
I would like to overlay dvipng rasters over an arbitrary background,
not just a solid color. My first thought was that one could extract
an alpha mask from the dvipng output by having dvipng blend black and
white and working out what the alpha at each pixel must have been
using the formula (I'm using the red channel but values are the same
for blue and green). First I run dvipng with

dvipng -bg Transparent -fg 'rgb 0.0 0.0 0.0' -D 100 -T tight -o outfile.png somefile.dvi


red = alpha*red_foreground + (1-alpha)*red_background


Since the foreground is black (0) and the background is white (1) this
reduces to red = 1-alpha or

alpha = 1-red


This gives be an MxN arrays of an alpha mask, and I then blend the
dvipng raster over an arbitrary background.

The problem is that the small rasters blended this way don't come out
as nicely as the ones rendered by dvipng assuming a constant
background. So I must be making some error in my logic. At first I
thought I might not be handling gamma properly, but I'm using gamma=1
so I don't have any special correction for that AFAIK. I also
wondered if I'm using the wrong blending formula -- eg is dvipng using
premultiplied alpha or some other formula to blend.

So my questions are

* would it be possible to modify dvipng to have an option to simply
return an alpha mask so we could blend dvi rasters over arbitrary
backgrounds?

* is there a way to calculate this mask from the output of dvipng as
it stands?

Thanks!

JDH
Bob McElrath
2005-05-18 18:25:53 UTC
Permalink
I use the following sequence of commands using python's Imaging library:

im = Image.open(os.path.join(workingDir, imname))
im2 = Image.new('RGBA', (im.size[0], im.size[1]), (255,255,255))
im2.paste(im, (0, 0))

To explicitly create an alpha channel I use:
alpha = ImageChops.invert(im.convert('L'))
im = im.putalpha(alpha)

This creates a PNG with a proper alpha channel. I would VERY much like
it if dvipng did this for me. I would love it if you could hack it in
to dvipng.

The code is in latexwiki http://mcelrath.org/Notes/LatexWiki in case I
have omitted some important step in the above code.
Post by John Hunter
I would like to overlay dvipng rasters over an arbitrary background,
not just a solid color. My first thought was that one could extract
an alpha mask from the dvipng output by having dvipng blend black and
white and working out what the alpha at each pixel must have been
using the formula (I'm using the red channel but values are the same
for blue and green). First I run dvipng with
dvipng -bg Transparent -fg 'rgb 0.0 0.0 0.0' -D 100 -T tight -o outfile.png somefile.dvi
red = alpha*red_foreground + (1-alpha)*red_background
Since the foreground is black (0) and the background is white (1) this
reduces to red = 1-alpha or
alpha = 1-red
This gives be an MxN arrays of an alpha mask, and I then blend the
dvipng raster over an arbitrary background.
The problem is that the small rasters blended this way don't come out
as nicely as the ones rendered by dvipng assuming a constant
background. So I must be making some error in my logic. At first I
thought I might not be handling gamma properly, but I'm using gamma=1
so I don't have any special correction for that AFAIK. I also
wondered if I'm using the wrong blending formula -- eg is dvipng using
premultiplied alpha or some other formula to blend.
So my questions are
* would it be possible to modify dvipng to have an option to simply
return an alpha mask so we could blend dvi rasters over arbitrary
backgrounds?
* is there a way to calculate this mask from the output of dvipng as
it stands?
Thanks!
JDH
_______________________________________________
Dvipng mailing list
http://lists.nongnu.org/mailman/listinfo/dvipng
--
Cheers,
Bob McElrath [Univ. of California at Davis, Department of Physics]

Censorship is never over for those who have experienced it. It is a brand
on the imagination that affects the individual who has suffered it,
forever. -- Noam Chomsky
Jan-Åke Larsson
2005-05-20 10:42:24 UTC
Permalink
Post by Bob McElrath
im = Image.open(os.path.join(workingDir, imname))
im2 = Image.new('RGBA', (im.size[0], im.size[1]), (255,255,255))
im2.paste(im, (0, 0))
alpha = ImageChops.invert(im.convert('L'))
im = im.putalpha(alpha)
This creates a PNG with a proper alpha channel. I would VERY much like
it if dvipng did this for me. I would love it if you could hack it in
to dvipng.
Unless I am mistaken, the CVS version of dvipng does create a
proper-alpha PNG if you use '-bg Transparent' (capital T). This is to be
released very soon as dvipng-1.6. Please try it out, I'd like to remove
any remaining flaws.

/JÅ
John Hunter
2005-05-22 16:49:01 UTC
Permalink
Post by Bob McElrath
I use the following sequence of commands using python's Imaging
library: im = Image.open(os.path.join(workingDir, imname)) im2
= Image.new('RGBA', (im.size[0], im.size[1]), (255,255,255))
im2.paste(im, (0, 0)) To explicitly create an alpha channel I
use: alpha = ImageChops.invert(im.convert('L')) im =
im.putalpha(alpha) This creates a PNG with a proper alpha
channel. I would VERY much like it if dvipng did this for me.
I would love it if you could hack it in to dvipng.
Jan-�ke> Unless I am mistaken, the CVS version of dvipng does
Jan-�ke> create a proper-alpha PNG if you use '-bg Transparent'
Jan-�ke> (capital T). This is to be released very soon as
Jan-�ke> dvipng-1.6. Please try it out, I'd like to remove any
Jan-�ke> remaining flaws.

It does not appear to, or I am misunderstanding something. I got a
CVS checkout today from


cvs -z3 -d:ext:***@savannah.nongnu.org:/cvsroot/dvipng co dvipng

and here is the summary of my config

** Configuration summary for dvipng 1.5:

The -d (debug) switch is enabled: yes
Your gd is new enough to enable
the -z (compression) switch: yes
Your gd is new enough to enable
the --truecolor switch: yes
Your gd is new enough to enable
gif support (dvigif): yes
FreeType font rendering available: yes
T1lib font rendering available: no


If I then create a png with, for example,
/usr/local/bin/dvipng -bg Transparent -fg 'rgb 0.0 0.0 0.0' -D 96 -T tight -o somefile.png somefile.dvi
and load the PNG into an array, all the values for the alpha channel
are either 0 or 1. To overlay this image on an arbitrary background,
I would expect the alpha for the pixels on the edge to vary. Here is
what I am doing (X is a MxNx4 array loaded from the png, and r,g,b are
the colors I want my text to be when I overlay it onto my own image

# I ignore the r,g,b channels of X because they have foreground
# and background color information in them which is not appropriate
# for overlay on an arbitrary background
alpha = X[:,:,3]
Z = zeros(X.shape, Float)
Z[:,:,0] = r
Z[:,:,1] = g
Z[:,:,2] = b
Z[:,:,3] = alpha

The version number I get from dvipng cvs still says 1.5. So I have
the latest -- does the CVS mirror lag behind?


peds-pc311:~/python/projects/matplotlib> /usr/local/bin/dvipng --version This is /usr/local/bin/dvipng 1.5 Copyright 2002-2005 Jan-Ake Larsson
dvipng 1.5
kpathsea version 3.4.5
Copyright (C) 2002-2005 Jan-Ake Larsson.
There is NO warranty. You may redistribute this software
under the terms of the GNU General Public License.
For more information about these matters, see the files
named COPYING and dvipng.c.

Thanks!
JDH
Jan-Åke Larsson
2005-05-24 07:36:27 UTC
Permalink
Jan-Åke> Unless I am mistaken, the CVS version of dvipng does
Jan-Åke> create a proper-alpha PNG if you use '-bg Transparent'
Jan-Åke> (capital T). This is to be released very soon as
Jan-Åke> dvipng-1.6. Please try it out, I'd like to remove any
Jan-Åke> remaining flaws.
It does not appear to, or I am misunderstanding something. I got a
CVS checkout today
[...]

This was solved by rerunning autoconf. (Mental note: perhaps a README.CVS?)

/JÅ

Loading...