xmlgraphics-batik-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Huang Haitao-G17843 <haitaohu...@motorola.com>
Subject RE: How do I encode SVG into PNG with lower color depth
Date Fri, 16 Aug 2002 16:32:29 GMT
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:thomas.deweese@kodak.com]
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 <haitaohuang@motorola.com> 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: batik-users-unsubscribe@xml.apache.org
For additional commands, e-mail: batik-users-help@xml.apache.org

---------------------------------------------------------------------
To unsubscribe, e-mail: batik-users-unsubscribe@xml.apache.org
For additional commands, e-mail: batik-users-help@xml.apache.org


Mime
View raw message