Hi Thierry,

Merci for your reply.

> My first comment is that instead of having a new
> transcoder, we should be able to leverage the current
> PNGTranscoder and just add a new TranscodingHint such as
> KEY_INDEXED_IMAGE: True | False - and add your code
> directly in the PNGTranscoder.

I agree with you.
And I've just done it.
The source is attached to this e-mail.

In my previous source, I explicitly set the RGB palette on PNGEncodeParam.Palette.
But, I found that:
   org.apache.batik.ext.awt.image.codec.PNGImageEncoder
is wise enough to set them, if they are not set yet.
The new code fragment is much simpler.

Only the problem is...
When the SVG include the complex image (such as photo), the indexed PNG looks somewhat 
ugly :-(
In case of RGB-PNG, this never happens.
What is wrong?

Anyway, you seem to be very busy for the new release.
Because my proposal is not the critical problem at all, please don't take your time 
for my source so soon.
When you have a time, please look into it and consider to commit it.

Happy Java programming!
--------------------------
Jun Inamori
OOP-Reserch
E-mail: [EMAIL PROTECTED]
URL:    http://www.oop-reserch.com/
/*****************************************************************************
 * Copyright (C) The Apache Software Foundation. All rights reserved.        *
 * ------------------------------------------------------------------------- *
 * This software is published under the terms of the Apache Software License *
 * version 1.1, a copy of which has been included with this distribution in  *
 * the LICENSE file.                                                         *
 *****************************************************************************/

package org.apache.batik.transcoder.image;

import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import java.awt.image.SinglePixelPackedSampleModel;
import java.io.IOException;
import java.io.OutputStream;
import org.apache.batik.transcoder.keys.BooleanKey;
import org.apache.batik.transcoder.TranscoderException;
import org.apache.batik.transcoder.TranscoderOutput;
import org.apache.batik.transcoder.TranscodingHints;
import org.apache.batik.transcoder.image.resources.Messages;
import org.apache.batik.ext.awt.image.codec.PNGEncodeParam;
import org.apache.batik.ext.awt.image.codec.PNGImageEncoder;

// By Jun Inamori ([EMAIL PROTECTED])
import java.awt.image.IndexColorModel;

/**
 * This class is an <tt>ImageTranscoder</tt> that produces a PNG image.
 *
 * @author <a href="mailto:[EMAIL PROTECTED]";>Thierry Kormann</a>
 * @version $Id: PNGTranscoder.java,v 1.9 2001/10/29 17:38:27 tkormann Exp $
 */
public class PNGTranscoder extends ImageTranscoder {
    /**
     * Constructs a new transcoder that produces png images.
     */
    public PNGTranscoder() { 
        hints.put(KEY_FORCE_TRANSPARENT_WHITE, new Boolean(false));
        // Start: By Jun Inamori ([EMAIL PROTECTED])
        hints.put(KEY_INDEXED_PNG, new Boolean(false));
        hints.put(KEY_INTERLACING, new Boolean(false));
        // End: By Jun Inamori ([EMAIL PROTECTED])
    }

    /**
     * Creates a new ARGB image with the specified dimension.
     * @param width the image width in pixels
     * @param height the image height in pixels
     */
    public BufferedImage createImage(int width, int height) {
        // Start: By Jun Inamori ([EMAIL PROTECTED])
        boolean isIndexed = false;
        if (hints.containsKey(KEY_INDEXED_PNG)) {
            isIndexed=
                ((Boolean)hints.get
                 (KEY_INDEXED_PNG)).booleanValue();
        }
        if(isIndexed){
            return new BufferedImage(width, height, BufferedImage.TYPE_BYTE_INDEXED);
        }
        return new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
        // END: By Jun Inamori ([EMAIL PROTECTED])
    }

    /**
     * Writes the specified image to the specified output.
     * @param img the image to write
     * @param output the output where to store the image
     * @param TranscoderException if an error occured while storing the image
     */
    public void writeImage(BufferedImage img, TranscoderOutput output)
            throws TranscoderException {

        OutputStream ostream = output.getOutputStream();
        if (ostream == null) {
            throw new TranscoderException(
                Messages.formatMessage("png.badoutput", null));
        }

        // Start: By Jun Inamori ([EMAIL PROTECTED])
        PNGEncodeParam params=PNGEncodeParam.getDefaultEncodeParam(img);
        boolean isIndexed = false;
        if (hints.containsKey(KEY_INDEXED_PNG)) {
            isIndexed=
                ((Boolean)hints.get
                 (KEY_INDEXED_PNG)).booleanValue();
        }
        if(isIndexed){
            ((PNGEncodeParam.Palette)params).setBackgroundPaletteIndex(255);
        }
        else{
            ((PNGEncodeParam.RGB)params).setBackgroundRGB(new int [] { 255, 255, 255 
});
        }
        // We are using sRGB (gamma 2.2).
        params.setSRGBIntent(PNGEncodeParam.INTENT_PERCEPTUAL);

        boolean interlacing = false;
        if (hints.containsKey(KEY_INTERLACING)) {
            interlacing=
                ((Boolean)hints.get
                 (KEY_INTERLACING)).booleanValue();
        }
        params.setInterlacing(interlacing);
        // END: By Jun Inamori ([EMAIL PROTECTED])

        //
        // This is a trick so that viewers which do not support the alpha
        // channel will see a white background (and not a black one).
        //
        boolean forceTransparentWhite = false;

        if (hints.containsKey(KEY_FORCE_TRANSPARENT_WHITE)) {
            forceTransparentWhite = 
                ((Boolean)hints.get
                 (KEY_FORCE_TRANSPARENT_WHITE)).booleanValue();
        }

        if (forceTransparentWhite) {
            int w = img.getWidth(), h = img.getHeight();
            DataBufferInt biDB = (DataBufferInt)img.getRaster().getDataBuffer();
            int scanStride = ((SinglePixelPackedSampleModel)
                              img.getSampleModel()).getScanlineStride();
            int dbOffset = biDB.getOffset();
            int pixels[] = biDB.getBankData()[0];
            int p = dbOffset;
            int adjust = scanStride - w;
            int a=0, r=0, g=0, b=0, pel=0;
            for(int i=0; i<h; i++){
                for(int j=0; j<w; j++){
                    pel = pixels[p];
                    a = (pel >> 24) & 0xff;
                    r = (pel >> 16) & 0xff;
                    g = (pel >> 8 ) & 0xff;
                    b =  pel        & 0xff;
                    r = (255*(255 -a) + a*r)/255;
                    g = (255*(255 -a) + a*g)/255;
                    b = (255*(255 -a) + a*b)/255;
                    pixels[p++] =
                        (a<<24 & 0xff000000) |
                        (r<<16 & 0xff0000) |
                        (g<<8  & 0xff00) |
                        (b     & 0xff);
                }
                p += adjust;
            }
        }

        try {
            PNGImageEncoder pngEncoder = new PNGImageEncoder(ostream, params);
            pngEncoder.encode(img);
            ostream.close();
        } catch (IOException ex) {
            throw new TranscoderException(ex);
        }
    }

    // --------------------------------------------------------------------
    // Keys definition
    // --------------------------------------------------------------------

    /**
     * The 'forceTransparentWhite' key.  It controls whether the encoder should
     * force the image's fully transparent pixels to be fully transparent white
     * instead of fully transparent black.  This is usefull when the encoded PNG
     * is displayed in a browser which does not support PNG transparency and
     * lets the image display with a white background instead of a black
     * background. <br /> However, note that the modified image will display
     * differently over a white background in a viewer that supports
     * transparency.  */
    public static final TranscodingHints.Key KEY_FORCE_TRANSPARENT_WHITE
        = new BooleanKey();

    // Start: By Jun Inamori ([EMAIL PROTECTED])
    public static final TranscodingHints.Key KEY_INDEXED_PNG
        = new BooleanKey();

    public static final TranscodingHints.Key KEY_INTERLACING
        = new BooleanKey();
    // End: By Jun Inamori ([EMAIL PROTECTED])
}

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to