You are viewing a plain text version of this content. The canonical link for it is here.
Posted to batik-dev@xmlgraphics.apache.org by de...@apache.org on 2002/06/22 13:52:56 UTC
cvs commit: xml-batik/sources/org/apache/batik/transcoder/image PNGTranscoder.java
deweese 2002/06/22 04:52:56
Modified: resources/org/apache/batik/apps/rasterizer/resources
Messages.properties
sources/org/apache/batik/apps/rasterizer Main.java
SVGConverter.java
sources/org/apache/batik/transcoder/image PNGTranscoder.java
Added: sources/org/apache/batik/ext/awt/image/rendered
IndexImage.java
Log:
1) Rasterizer now supports '-indexed' property when writting PNG images.
This will generate a 256 color indexed PNG image.
Revision Changes Path
1.8 +9 -3 xml-batik/resources/org/apache/batik/apps/rasterizer/resources/Messages.properties
Index: Messages.properties
===================================================================
RCS file: /home/cvs/xml-batik/resources/org/apache/batik/apps/rasterizer/resources/Messages.properties,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- Messages.properties 3 May 2002 07:41:46 -0000 1.7
+++ Messages.properties 22 Jun 2002 11:52:55 -0000 1.8
@@ -90,7 +90,10 @@
\tUser language to use when converting SVG documents.\n \
-q <quality> \n \
\tQuality for the output image. This is only relevant for the \n \
-image/jpeg mime type. \n \
+\timage/jpeg mime type. \n \
+ -indexed \n \
+\tReduces the image to 256 colors, resulting in an Indexed image.\n \
+\tThis is only used for PNG conversion.\n \
-dpi <resolution> \n \
\tResolution for the ouptut image. \n \
-validate \n \
@@ -167,11 +170,14 @@
Example: -cssUser myStylesheet.css
Default: none
-Main.cl.option.q.description = \
+Main.cl.option.quality.description = \
-q <quality> Quality for the generated output image. This is only used for JPEG conversion. \n \
-The value should be in the [0,1[ range. \n \
+The value should be in the [0,1] range. \n \
Example: -q 0.5
Default: 0.99
+
+Main.cl.option.indexed.description = \
+-indexed indicates that the image should be reduced to 256 colors, resulting in an Indexed image. This is only used for PNG conversion.
Main.cl.option.dpi.description = \
-dpi <resolution> Resolution for the output image. This is used to compute the \n \
1.22 +20 -1 xml-batik/sources/org/apache/batik/apps/rasterizer/Main.java
Index: Main.java
===================================================================
RCS file: /home/cvs/xml-batik/sources/org/apache/batik/apps/rasterizer/Main.java,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -r1.21 -r1.22
--- Main.java 21 Jun 2002 16:35:13 -0000 1.21
+++ Main.java 22 Jun 2002 11:52:56 -0000 1.22
@@ -420,6 +420,15 @@
= Messages.get("Main.cl.option.quality.description", "No description");
/**
+ * Option to specify if the PNG should be indexed.
+ */
+ public static String CL_OPTION_INDEXED
+ = Messages.get("Main.cl.option.indexed", "-indexed");
+
+ public static String CL_OPTION_INDEXED_DESCRIPTION
+ = Messages.get("Main.cl.option.indexed.description", "No description");
+
+ /**
* Option to specify the set of allowed scripts
*/
public static String CL_OPTION_ALLOWED_SCRIPTS
@@ -639,6 +648,16 @@
}
});
+ optionMap.put(CL_OPTION_INDEXED,
+ new NoValueOptionHandler(){
+ public void handleOption(SVGConverter c){
+ c.setIndexed(true);
+ }
+
+ public String getOptionDescription(){
+ return CL_OPTION_INDEXED_DESCRIPTION;
+ }
+ });
optionMap.put(CL_OPTION_VALIDATE,
new NoValueOptionHandler(){
public void handleOption(SVGConverter c){
1.15 +38 -11 xml-batik/sources/org/apache/batik/apps/rasterizer/SVGConverter.java
Index: SVGConverter.java
===================================================================
RCS file: /home/cvs/xml-batik/sources/org/apache/batik/apps/rasterizer/SVGConverter.java,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -r1.14 -r1.15
--- SVGConverter.java 17 Jun 2002 12:40:27 -0000 1.14
+++ SVGConverter.java 22 Jun 2002 11:52:56 -0000 1.15
@@ -14,6 +14,7 @@
import org.apache.batik.transcoder.TranscoderOutput;
import org.apache.batik.transcoder.image.ImageTranscoder;
import org.apache.batik.transcoder.image.JPEGTranscoder;
+import org.apache.batik.transcoder.image.PNGTranscoder;
import java.io.File;
import java.io.FileFilter;
@@ -62,19 +63,25 @@
* see the {@link DestinationType} documentation.</li>
* <li>width/height: they control the desired width and height, in user space,
* for the output image.</li>
- * <li>area: controls the specific sub-area of the image which should be rendered.</li>
- * <li>backgroundColor: controls the color which is used to fill the background
- * before rendering the image</li>
+ * <li>area: controls the specific sub-area of the image which should be
+ * rendered.</li>
+ * <li>backgroundColor: controls the color which is used to fill the
+ * background before rendering the image</li>
* <li>quality: relevant only for JPEG destinations, this controls the
- * encoding quality.</li>
+ * encoding quality.</li>
+ * <li>indexed: relevant only for PNG, controls the writting of
+ * indexed files.</li>
* <li>mediaType: controls the CSS media, or list of media, for which the
- * image should be rendered.</li>
- * <li>alternate: controls the alternate CSS stylesheet to activate, if any.</li>
- * <li>language: controls the user language with which the SVG document should
- * be converted.</li>
+ * image should be rendered.</li>
+ * <li>alternate: controls the alternate CSS stylesheet to activate,
+ * if any.</li>
+ * <li>language: controls the user language with which the SVG document
+ * should be converted.</li>
* <li>userStylesheet: defines the user stylesheet to apply to SVG documents
- * in addition to other stylesheets referenced by or embedded in the SVG documents.</li>
- * <li>pixelUnitToMillimeter: defines the size of a pixel in millimeters to use when processing the SVG documents.</li>
+ * in addition to other stylesheets referenced by or embedded in the
+ * SVG documents.</li>
+ * <li>pixelUnitToMillimeter: defines the size of a pixel in millimeters
+ * to use when processing the SVG documents.</li>
* </ul>
*
* @version $Id$
@@ -201,6 +208,9 @@
/** Output image quality. */
protected float quality = DEFAULT_QUALITY;
+ /** Should output Image be indexed . */
+ protected boolean indexed = false;
+
/** Output AOI area. */
protected Rectangle2D area = null;
@@ -338,6 +348,18 @@
}
/**
+ * Tells the PNG encoder to reduce the image to 256 colors, so the
+ * PNG file is indexed.
+ */
+ public void setIndexed(boolean indexed) throws IllegalArgumentException {
+ this.indexed = indexed;
+ }
+
+ public boolean getIndexed(){
+ return indexed;
+ }
+
+ /**
* Sets the user language. If the value is null, then the default (see
* {@link org.apache.batik.bridge.UserAgent#getLanguages})
* is used.
@@ -737,6 +759,11 @@
// Set image quality. ------------------------------------------------
if (quality > 0) {
map.put(JPEGTranscoder.KEY_QUALITY, new Float(this.quality));
+ }
+
+ // Set image indexed. ------------------------------------------------
+ if (indexed) {
+ map.put(PNGTranscoder.KEY_INDEXED, new Boolean(indexed));
}
// Set image background color -----------------------------------------
1.1 xml-batik/sources/org/apache/batik/ext/awt/image/rendered/IndexImage.java
Index: IndexImage.java
===================================================================
/*****************************************************************************
* 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.ext.awt.image.rendered;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.awt.image.IndexColorModel;
import java.util.Comparator;
import java.util.Vector;
import java.util.Iterator;
/**
* This implements an adaptive pallete generator to reduce images
* to 256 colors.
*
* This should probably be generalized to create a pallete with any number of
* colors in it (rather than always 256). This should be easy to do.
*
* Ideally this would also support a better dither option than just
* the JDK's pattern dither.
*
* @author <a href="mailto:deweese@apache.org">Thomas DeWeese</a>
* @author <a href="mailto:jun@oop-reserch.com">Jun Inamori</a>
* @version $Id: IndexImage.java,v 1.1 2002/06/22 11:52:56 deweese Exp $
*/
public class IndexImage{
/**
* Used to track a color and the number of pixels of that colors
*/
private static class Counter {
public int val;
public int count=1;
public Counter(int val) { this.val = val; }
public boolean add(int val) {
// See if the value matches us...
if (this.val != val)
return false;
count++;
return true;
}
}
/**
* Used to define a cube of the colorspace. The cube can be split
* approximagely in half to generate two cubes. */
private static class Cube {
int []min={0, 0, 0}, max={255,255,255};
boolean done = false;
Vector []colors = null;
int count=0;
static final int RED = 0;
static final int GRN = 1;
static final int BLU = 2;
/**
* Define a new cube.
* @param colors contains the 3D color histogram to be subdivided
* @param count the total number of pixels in the 3D histogram.
*/
public Cube(Vector []colors, int count) {
this.colors = colors;
this.count = count;
}
/**
* If this returns true then the cube can not be subdivided any
* further
*/
public boolean isDone() { return done; }
/**
* Splits the cube into two parts. This cube is
* changed to be one half and the returned cube is the other half.
* This tries to pick the right channel to split on.
*/
public Cube split() {
int dr = max[0]-min[0]+1;
int dg = max[1]-min[1]+1;
int db = max[2]-min[2]+1;
int c0, c1, splitChannel;
// Figure out which axis is the longest and split along
// that axis (this tries to keep cubes square-ish).
if (dr >= dg) {
c0 = GRN;
if (dr >= db) { splitChannel = RED; c1=BLU; }
else { splitChannel = BLU; c1=RED; }
} else if (dg >= db) {
splitChannel = GRN;
c0=RED;
c1=BLU;
} else {
splitChannel = BLU;
c0=RED;
c1=GRN;
}
Cube ret;
ret = splitChannel(splitChannel, c0, c1);
if (ret != null ) return ret;
ret = splitChannel(c0, splitChannel, c1);
if (ret != null ) return ret;
ret = splitChannel(c1, splitChannel, c0);
if (ret != null) return ret;
done = true;
return null;
}
/**
* Splits the image according to the parameters. It tries
* to find a location where half the pixels are on one side
* and half the pixels are on the other.
*/
public Cube splitChannel(int splitChannel, int c0, int c1) {
if (min[splitChannel] == max[splitChannel]) return null;
int splitSh4 = (2-splitChannel)*4;
int c0Sh4 = (2-c0)*4;
int c1Sh4 = (2-c1)*4;
int splitSh8 = (2-splitChannel)*8;
int c0Sh8 = (2-c0)*8;
int c1Sh8 = (2-c1)*8;
int half = count/2;
// Each entry is the number of pixels that have that value
// in the split channel within the cube (so pixels
// that have that value in the split channel aren't counted
// if they are outside the cube in the other color channels.
int counts [] = new int[256];
int tcount = 0;
// System.out.println("Cube: [" +
// min[0] + "-" + max[0] + "] [" +
// min[1] + "-" + max[1] + "] [" +
// min[2] + "-" + max[2] + "]");
int [] minIdx = {min[0]>>4, min[1]>>4, min[2]>>4};
int [] maxIdx = {max[0]>>4, max[1]>>4, max[2]>>4};
int minR=min[0], minG=min[1], minB=min[2];
int maxR=max[0], maxG=max[1], maxB=max[2];
int val = 0;
int [] vals = {0, 0, 0};
for (int i=minIdx[splitChannel]; i<=maxIdx[splitChannel]; i++) {
int idx1 = i<<splitSh4;
for (int j=minIdx[c0]; j<=maxIdx[c0]; j++) {
int idx2 = idx1 | (j<<c0Sh4);
for (int k=minIdx[c1]; k<=maxIdx[c1]; k++) {
int idx = idx2 | (k<<c1Sh4);
Vector v = colors[idx];
if (v==null) continue;
Iterator itr = v.iterator();
Counter c;
while (itr.hasNext()) {
c = (Counter)itr.next();
val = c.val;
vals[0] = (val&0xFF0000)>>16;
vals[1] = (val&0xFF00)>>8;
vals[2] = (val&0xFF);
if (((vals[0] >= minR) && (vals[0] <= maxR))&&
((vals[1] >= minG) && (vals[1] <= maxG))&&
((vals[2] >= minB) && (vals[2] <= maxB))) {
// The val lies within this cube so count it.
counts[vals[splitChannel]] += c.count;
tcount += c.count;
}
}
}
}
// We've found the half way point. Note that the
// rest of counts is not filled out.
if (tcount >= half) break;
}
tcount=0;
int lastAdd=-1;
// These indicate what the top value for the low cube and
// the low value of the high cube should be in the split channel
// (they may not be one off if there are 'dead' spots in the
// counts array.
int splitLo=min[splitChannel], splitHi=max[splitChannel];
for (int i=min[splitChannel]; i<=max[splitChannel]; i++) {
int c = counts[i];
if (c == 0) {
// No counts below this so move up bottom of cube.
if ((tcount == 0) && (i < max[splitChannel]))
this.min[splitChannel] = i+1;
continue;
}
if (tcount+c < half) {
lastAdd = i;
tcount+=c;
continue;
}
if ((half-tcount) <= ((tcount+c)-half)) {
// Then lastAdd is a better top idx for this then i.
if (lastAdd == -1) {
// No lower place to break.
if (c == this.count) {
// All pixels are at this value so make min/max
// reflect that.
this.max[splitChannel] = i;
return null; // no split to make.
} else {
// There are values about this one so
// split above.
splitLo = i;
splitHi = i+1;
break;
}
}
splitLo = lastAdd;
splitHi = i;
} else {
if (i == this.max[splitChannel]) {
if ( c == this.count) {
// would move min up but that should
// have happened already.
return null; // no split to make.
} else {
// Would like to break between i and i+1
// but no i+1 so use lastAdd and i;
splitLo = lastAdd;
splitHi = i;
break;
}
}
// Include c in counts
tcount += c;
splitLo = i;
splitHi = i+1;
}
break;
}
// System.out.println("Split: " + splitChannel + "@"
// + splitLo + "-"+splitHi +
// " Count: " + tcount + " of " + count +
// " LA: " + lastAdd);
// Create the new cube and update everone's bounds & counts.
Cube ret = new Cube(colors, tcount);
this.count = this.count-tcount;
ret.min[splitChannel] = this.min[splitChannel];
ret.max[splitChannel] = splitLo;
this.min[splitChannel] = splitHi;
ret.min[c0] = this.min[c0];
ret.max[c0] = this.max[c0];
ret.min[c1] = this.min[c1];
ret.max[c1] = this.max[c1];
return ret;
}
/**
* Returns the average color for this cube
*/
public int averageColor() {
if (this.count == 0) return 0;
float red=0, grn=0, blu=0;
int minR=min[0], minG=min[1], minB=min[2];
int maxR=max[0], maxG=max[1], maxB=max[2];
int [] minIdx = {minR>>4, minG>>4, minB>>4};
int [] maxIdx = {maxR>>4, maxG>>4, maxB>>4};
int val, ired, igrn, iblu;
float weight;
for (int i=minIdx[0]; i<=maxIdx[0]; i++) {
int idx1 = i<<8;
for (int j=minIdx[1]; j<=maxIdx[1]; j++) {
int idx2 = idx1 | (j<<4);
for (int k=minIdx[2]; k<=maxIdx[2]; k++) {
int idx = idx2 | k;
Vector v = colors[idx];
if (v==null) continue;
Iterator itr = v.iterator();
Counter c;
while (itr.hasNext()) {
c = (Counter)itr.next();
val = c.val;
ired = (val&0xFF0000)>>16;
igrn = (val&0x00FF00)>>8;
iblu = (val&0x0000FF);
if (((ired >= minR) && (ired <= maxR))&&
((igrn >= minG) && (igrn <= maxG))&&
((iblu >= minB) && (iblu <= maxB))) {
weight = (c.count/(float)this.count);
red += ((float)ired)*weight;
grn += ((float)igrn)*weight;
blu += ((float)iblu)*weight;
}
}
}
}
}
// System.out.println("RGB: [" + red + ", " +
// grn + ", " + blu + "]");
return (((int)(red+0.5))<<16 |
((int)(grn+0.5))<<8 |
((int)(blu+0.5)));
}
}
/**
* Converts the input image (must be TYPE_INT_RGB or
* TYPE_INT_ARGB) to an indexed image. Generating an adaptive
* pallete.
*/
static public BufferedImage getIndexedImage(BufferedImage bi){
int w=bi.getWidth();
int h=bi.getHeight();
// Using 4 bits from RG & B.
Vector [] colors = new Vector[1<<12];
int rgb=0;
for(int i_w=0; i_w<w; i_w++){
for(int i_h=0; i_h<h; i_h++){
rgb=(bi.getRGB(i_w,i_h) & 0xFFFFFF);
// Get index from high four bits of each component.
int idx = (((rgb&0xF00000)>>> 12) |
((rgb&0x00F000)>>> 8) |
((rgb&0x0000F0)>>> 4));
// Get the 'hash vector' for that key.
Vector v = colors[idx];
if (v == null) {
// No colors in this bin yet so create vector and
// add color.
v = new Vector();
v.add(new Counter(rgb));
colors[idx] = v;
} else {
// find our color in the bin or create a counter for it.
Iterator i = v.iterator();
while (true) {
if (i.hasNext()) {
// try adding our color to each counter...
if (((Counter)i.next()).add(rgb)) break;
} else {
v.add(new Counter(rgb));
break;
}
}
}
}
}
int nCubes=1;
int fCube=0;
Cube [] cubes = new Cube[256];
cubes[0] = new Cube(colors, w*h);
while (nCubes < 256) {
while (cubes[fCube].isDone()) {
fCube++;
if (fCube == nCubes) break;
}
if (fCube == nCubes) break;
Cube c = cubes[fCube];
Cube nc = c.split();
if (nc != null) {
if (nc.count > c.count) {
Cube tmp = c; c= nc; nc = tmp;
}
int j = fCube;
int cnt = c.count;
for (int i=fCube+1; i<nCubes; i++) {
if (cubes[i].count < cnt)
break;
cubes[j++] = cubes[i];
}
cubes[j++] = c;
cnt = nc.count;
while (j<nCubes) {
if (cubes[j].count < cnt)
break;
j++;
}
for (int i=nCubes; i>j; i--)
cubes[i] = cubes[i-1];
cubes[j++] = nc;
nCubes++;
}
}
byte [] r = new byte[nCubes];
byte [] g = new byte[nCubes];
byte [] b = new byte[nCubes];
for (int i=0; i<nCubes; i++) {
int val = cubes[i].averageColor();
r[i] = (byte)((val>>16)&0xFF);
g[i] = (byte)((val>> 8)&0xFF);
b[i] = (byte)((val )&0xFF);
}
IndexColorModel model=new IndexColorModel(4,256,r,g,b);
BufferedImage indexed=new BufferedImage
(w, h, BufferedImage.TYPE_BYTE_INDEXED,model);
Graphics2D g2d=indexed.createGraphics();
g2d.setRenderingHint
(RenderingHints.KEY_DITHERING,RenderingHints.VALUE_DITHER_ENABLE);
g2d.drawImage(bi, 0, 0, null);
g2d.dispose();
return indexed;
}
}
1.15 +44 -40 xml-batik/sources/org/apache/batik/transcoder/image/PNGTranscoder.java
Index: PNGTranscoder.java
===================================================================
RCS file: /home/cvs/xml-batik/sources/org/apache/batik/transcoder/image/PNGTranscoder.java,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -r1.14 -r1.15
--- PNGTranscoder.java 5 Jun 2002 21:14:48 -0000 1.14
+++ PNGTranscoder.java 22 Jun 2002 11:52:56 -0000 1.15
@@ -21,6 +21,7 @@
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;
+import org.apache.batik.ext.awt.image.rendered.IndexImage;
/**
* This class is an <tt>ImageTranscoder</tt> that produces a PNG image.
@@ -60,24 +61,6 @@
throw new TranscoderException(
Messages.formatMessage("png.badoutput", null));
}
- PNGEncodeParam.RGB params =
- (PNGEncodeParam.RGB)PNGEncodeParam.getDefaultEncodeParam(img);
- params.setBackgroundRGB(new int [] { 255, 255, 255 });
-
- // If they specify GAMMA key then use it otherwise don't
- // write a gAMA chunk, (default Gamma=2.2).
- if (hints.containsKey(KEY_GAMMA)) {
- params.setGamma(((Float)hints.get(KEY_GAMMA)).floatValue());
- }
-
- // We always want an sRGB chunk and Our encoding intent is
- // perceptual
- params.setSRGBIntent(PNGEncodeParam.INTENT_PERCEPTUAL);
-
- float PixSzMM = userAgent.getPixelUnitToMillimeter();
- // num Pixs in 1 Meter
- int numPix = (int)((1000/PixSzMM)+0.5);
- params.setPhysicalDimension(numPix, numPix, 1); // 1 means 'pix/meter'
//
// This is a trick so that viewers which do not support the alpha
@@ -121,6 +104,32 @@
}
}
+ if (hints.containsKey(KEY_INDEXED)) {
+ if (((Boolean)hints.get(KEY_INDEXED)).booleanValue())
+ img = IndexImage.getIndexedImage(img);
+ }
+
+ PNGEncodeParam params = PNGEncodeParam.getDefaultEncodeParam(img);
+ if (params instanceof PNGEncodeParam.RGB) {
+ ((PNGEncodeParam.RGB)params).setBackgroundRGB
+ (new int [] { 255, 255, 255 });
+ }
+
+ // If they specify GAMMA key then use it otherwise don't
+ // write a gAMA chunk, (default Gamma=2.2).
+ if (hints.containsKey(KEY_GAMMA)) {
+ params.setGamma(((Float)hints.get(KEY_GAMMA)).floatValue());
+ }
+
+ // We always want an sRGB chunk and Our encoding intent is
+ // perceptual
+ params.setSRGBIntent(PNGEncodeParam.INTENT_PERCEPTUAL);
+
+ float PixSzMM = userAgent.getPixelUnitToMillimeter();
+ // num Pixs in 1 Meter
+ int numPix = (int)((1000/PixSzMM)+0.5);
+ params.setPhysicalDimension(numPix, numPix, 1); // 1 means 'pix/meter'
+
try {
PNGImageEncoder pngEncoder = new PNGImageEncoder(ostream, params);
pngEncoder.encode(img);
@@ -135,59 +144,54 @@
// --------------------------------------------------------------------
/**
- * The forceTransparentWhite key.
+ * The gamma correction key.
*
* <TABLE BORDER="0" CELLSPACING="0" CELLPADDING="1">
* <TR>
* <TH VALIGN="TOP" ALIGN="RIGHT"><P ALIGN="RIGHT">Key: </TH>
- * <TD VALIGN="TOP">KEY_FORCE_TRANSPARENT_WHITE</TD></TR>
+ * <TD VALIGN="TOP">KEY_GAMMA</TD></TR>
* <TR>
* <TH VALIGN="TOP" ALIGN="RIGHT"><P ALIGN="RIGHT">Value: </TH>
- * <TD VALIGN="TOP">Boolean</TD></TR>
+ * <TD VALIGN="TOP">Float</TD></TR>
* <TR>
* <TH VALIGN="TOP" ALIGN="RIGHT"><P ALIGN="RIGHT">Default: </TH>
- * <TD VALIGN="TOP">false</TD></TR>
+ * <TD VALIGN="TOP">PNGEncodeParam.INTENT_PERCEPTUAL</TD></TR>
* <TR>
* <TH VALIGN="TOP" ALIGN="RIGHT"><P ALIGN="RIGHT">Required: </TH>
* <TD VALIGN="TOP">No</TD></TR>
* <TR>
* <TH VALIGN="TOP" ALIGN="RIGHT"><P ALIGN="RIGHT">Description: </TH>
- * <TD VALIGN="TOP">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.</TD></TR>
+ * <TD VALIGN="TOP">Controls the gamma correction of the png image.</TD>
+ * </TR>
* </TABLE>
*/
- public static final TranscodingHints.Key KEY_FORCE_TRANSPARENT_WHITE
- = ImageTranscoder.KEY_FORCE_TRANSPARENT_WHITE;
+ public static final TranscodingHints.Key KEY_GAMMA
+ = new FloatKey();
/**
- * The gamma correction key.
+ * The write a 256 color indexed image key.
*
* <TABLE BORDER="0" CELLSPACING="0" CELLPADDING="1">
* <TR>
* <TH VALIGN="TOP" ALIGN="RIGHT"><P ALIGN="RIGHT">Key: </TH>
- * <TD VALIGN="TOP">KEY_GAMMA</TD></TR>
+ * <TD VALIGN="TOP">KEY_INDEXED</TD></TR>
* <TR>
* <TH VALIGN="TOP" ALIGN="RIGHT"><P ALIGN="RIGHT">Value: </TH>
- * <TD VALIGN="TOP">Float</TD></TR>
+ * <TD VALIGN="TOP">Boolean</TD></TR>
* <TR>
* <TH VALIGN="TOP" ALIGN="RIGHT"><P ALIGN="RIGHT">Default: </TH>
- * <TD VALIGN="TOP">PNGEncodeParam.INTENT_PERCEPTUAL</TD></TR>
+ * <TD VALIGN="TOP">False</TD></TR>
* <TR>
* <TH VALIGN="TOP" ALIGN="RIGHT"><P ALIGN="RIGHT">Required: </TH>
* <TD VALIGN="TOP">No</TD></TR>
* <TR>
* <TH VALIGN="TOP" ALIGN="RIGHT"><P ALIGN="RIGHT">Description: </TH>
- * <TD VALIGN="TOP">Controls the gamma correction of the png image.</TD>
+ * <TD VALIGN="TOP">Turns on the reduction of the image to 256 colors.
+ * The resultant PNG will be an indexed PNG with 256 colors.</TD>
* </TR>
* </TABLE>
*/
- public static final TranscodingHints.Key KEY_GAMMA
- = new FloatKey();
+ public static final TranscodingHints.Key KEY_INDEXED
+ = new BooleanKey();
}
---------------------------------------------------------------------
To unsubscribe, e-mail: batik-dev-unsubscribe@xml.apache.org
For additional commands, e-mail: batik-dev-help@xml.apache.org