Thanks for the info. I looked the latest version.
I modified the IndexedImage.getIndexedImage() to accept a integer n to specify num of
colors, and replaced the hardcoded 256 to n. I'm not sure if I need make other
modifications. I'd appreciate your further directions.
Encoding the same SVG into PNGs with depth of 1,2,4,8 works ok, but to my suprise is
that the PNG with depth 4 has larger file size than the one with depth 8, and 2 is
larger than 4 and has the same size as the orignal with default 24 depth. Depth 1
gives me 3 colors but has the smallest file size.
Do i need specify different bitsize for different color depth when construct the
IndexColorModel?
Use different mask instead of 0xFF to construct the r,g,b palette arrays?
Thanks
Haitao
========================================
static public BufferedImage getIndexedImage(BufferedImage bi,int n){
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[n];
cubes[0] = new Cube(colors, w*h);
while (nCubes < n) {
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,n,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;
}
=============================================================
-----Original Message-----
From: Thomas E Deweese [mailto:[EMAIL PROTECTED]]
Sent: Tuesday, August 13, 2002 9:45 AM
To: Batik Users
Subject: RE: How do I encode SVG into PNG with lower color depth
>>>>> "HH" == Huang Haitao-G17843 <[EMAIL PROTECTED]> writes:
HH> I didn' find class IndexImage,
I think you need to use current CVS.
It is sources/org/apache/batik/ext/awt/image/rendered/IndexImage.java
HH> If I use indexed PNG, is 8 the lowest depth I can get?
No but the IndexImage in CVS only ever generates a 256 color
pallete if you modify it to create a 16 color pallete I think the PNG
encoder will write a 4bit pallete PNG.
HH> Do I need use PNGEncodeParam.Gray or PNGEncodeParam.Palette?
HH> Which part of the code should I plug in the IndexImage you talked
HH> about? Would it matter if the SVG specifies color in RGB?
If the SVG has too many colors it will look poor in such low bit
depths but if it is simple it should come through pretty well.
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]