Cleaned up the NIO buffered image classes.

This commit is contained in:
Harald Kuhr 2010-06-13 20:29:25 +02:00
parent 7d4d007975
commit 9d6f263b86
2 changed files with 63 additions and 31 deletions

View File

@ -3,42 +3,30 @@ package com.twelvemonkeys.image;
import javax.swing.*; import javax.swing.*;
import java.awt.*; import java.awt.*;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.DataBuffer; import java.awt.image.DataBuffer;
import java.awt.image.SampleModel;
import java.io.IOException; import java.io.IOException;
import java.util.Random; import java.util.Random;
/** /**
* MappedBufferedImageFactory * MappedBufferImage
* *
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a> * @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
* @author last modified by $Author: haraldk$ * @author last modified by $Author: haraldk$
* @version $Id: MappedBufferedImageFactory.java,v 1.0 May 26, 2010 5:07:01 PM haraldk Exp$ * @version $Id: MappedBufferImage.java,v 1.0 Jun 13, 2010 7:33:19 PM haraldk Exp$
*/ */
public class MappedBufferedImageFactory { public class MappedBufferImage {
private static final boolean ALPHA = true; private static final boolean ALPHA = true;
public static void main(String[] args) throws IOException { public static void main(String[] args) throws IOException {
int w = args.length > 0 ? Integer.parseInt(args[0]) : 6000; int w = args.length > 0 ? Integer.parseInt(args[0]) : 6000;
int h = args.length > 1 ? Integer.parseInt(args[1]) : w * 2 / 3; int h = args.length > 1 ? Integer.parseInt(args[1]) : w * 2 / 3;
ColorModel cm = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice(). GraphicsConfiguration configuration = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
getDefaultConfiguration().getColorModel(ALPHA ? Transparency.TRANSLUCENT : Transparency.OPAQUE); BufferedImage image = MappedImageFactory.createCompatibleMappedImage(w, h, configuration, MappedBufferImage.ALPHA ? Transparency.TRANSLUCENT : Transparency.OPAQUE);
// ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
// ColorModel cm = new ComponentColorModel(cs, ALPHA, false, ALPHA ? TRANSLUCENT : OPAQUE, DataBuffer.TYPE_BYTE);
SampleModel sm = cm.createCompatibleSampleModel(w, h);
// System.err.println("cm: " + cm); System.out.println("image = " + image);
// System.err.println("cm.getNumComponents(): " + cm.getNumComponents());
// System.err.println("cm.getPixelSize(): " + cm.getPixelSize());
// System.err.println("cm.getComponentSize(): " + Arrays.toString(cm.getComponentSize()));
// System.err.println("sm.getNumDataElements(): " + sm.getNumDataElements());
// System.err.println("sm.getNumBands(): " + sm.getNumBands());
// System.err.println("sm.getSampleSize(): " + Arrays.toString(sm.getSampleSize()));
DataBuffer buffer = MappedFileBuffer.create(sm.getTransferType(), w * h * sm.getNumDataElements(), 1); DataBuffer buffer = image.getRaster().getDataBuffer();
// DataBuffer buffer = sm.createDataBuffer();
// Mix in some nice colors // Mix in some nice colors
for (int y = 0; y < h; y++) { for (int y = 0; y < h; y++) {
@ -48,7 +36,7 @@ public class MappedBufferedImageFactory {
int b = (int) ((x * (h - y) * 255.0) / (h * w)); int b = (int) ((x * (h - y) * 255.0) / (h * w));
int a = ALPHA ? (int) (((w - x) * (h - y) * 255.0) / (h * w)) : 0; int a = ALPHA ? (int) (((w - x) * (h - y) * 255.0) / (h * w)) : 0;
switch (cm.getTransferType()) { switch (buffer.getDataType()) {
case DataBuffer.TYPE_BYTE: case DataBuffer.TYPE_BYTE:
int off = (y * w + x) * (ALPHA ? 4 : 3); int off = (y * w + x) * (ALPHA ? 4 : 3);
if (ALPHA) { if (ALPHA) {
@ -58,7 +46,7 @@ public class MappedBufferedImageFactory {
buffer.setElem(off, r); buffer.setElem(off, r);
} }
else { else {
// TODO: Why RGB / ABGR?? // TODO: Why the RGB / ABGR byte order inconsistency??
buffer.setElem(off++, r); buffer.setElem(off++, r);
buffer.setElem(off++, g); buffer.setElem(off++, g);
buffer.setElem(off, b); buffer.setElem(off, b);
@ -68,17 +56,11 @@ public class MappedBufferedImageFactory {
buffer.setElem(y * w + x, (255 - a) << 24 | r << 16 | g << 8 | b); buffer.setElem(y * w + x, (255 - a) << 24 | r << 16 | g << 8 | b);
break; break;
default: default:
System.err.println("Transfer type not supported: " + cm.getTransferType()); System.err.println("Transfer type not supported: " + buffer.getDataType());
} }
} }
} }
BufferedImage image = new BufferedImage(cm, new GenericWritableRaster(sm, buffer, new Point()), cm.isAlphaPremultiplied(), null);
// BufferedImage image = new BufferedImage(cm, new SunWritableRaster(sm, buffer, new Point()), cm.isAlphaPremultiplied(), null);
// BufferedImage image = new BufferedImage(cm, Raster.createWritableRaster(sm, buffer, null), false null);
System.out.println("image = " + image);
// Add some random dots (get out the coffee) // Add some random dots (get out the coffee)
int s = 300; int s = 300;
int ws = w / s; int ws = w / s;
@ -101,6 +83,7 @@ public class MappedBufferedImageFactory {
} }
catch (OutOfMemoryError e) { catch (OutOfMemoryError e) {
System.gc(); System.gc();
System.err.println("Out of memory: " + e.getMessage());
g = tile.createGraphics(); // If this fails, give up g = tile.createGraphics(); // If this fails, give up
} }
@ -171,7 +154,8 @@ public class MappedBufferedImageFactory {
@Override @Override
protected void paintComponent(Graphics g) { protected void paintComponent(Graphics g) {
// TODO: Figure out why mouse wheel/track pad scroll repaints entire component, // TODO: Figure out why mouse wheel/track pad scroll repaints entire component,
// consider creating a custom mouse wheel listener as a workaround // unlike using the scroll bars of the JScrollPane.
// Consider creating a custom mouse wheel listener as a workaround.
// We want to paint only the visible part of the image // We want to paint only the visible part of the image
Rectangle visible = getVisibleRect(); Rectangle visible = getVisibleRect();
@ -255,6 +239,5 @@ public class MappedBufferedImageFactory {
public boolean getScrollableTracksViewportHeight() { public boolean getScrollableTracksViewportHeight() {
return false; return false;
} }
} }
} }

View File

@ -0,0 +1,49 @@
package com.twelvemonkeys.image;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.DataBuffer;
import java.awt.image.SampleModel;
import java.io.IOException;
/**
* MappedImageFactory
*
* @author <a href="mailto:harald.kuhr@gmail.com">Harald Kuhr</a>
* @author last modified by $Author: haraldk$
* @version $Id: MappedImageFactory.java,v 1.0 May 26, 2010 5:07:01 PM haraldk Exp$
*/
public class MappedImageFactory {
public static BufferedImage createCompatibleMappedImage(int width, int height, int type) throws IOException {
return createCompatibleMappedImage(width, height, new BufferedImage(1, 1, type).getColorModel());
}
public static BufferedImage createCompatibleMappedImage(int width, int height, GraphicsConfiguration configuration, int transparency) throws IOException {
ColorModel cm = configuration.getColorModel(transparency);
// ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
// ColorModel cm = new ComponentColorModel(cs, ALPHA, false, ALPHA ? TRANSLUCENT : OPAQUE, DataBuffer.TYPE_BYTE);
return createCompatibleMappedImage(width, height, cm);
}
private static BufferedImage createCompatibleMappedImage(int width, int height, ColorModel cm) throws IOException {
SampleModel sm = cm.createCompatibleSampleModel(width, height);
// System.err.println("cm: " + cm);
// System.err.println("cm.getNumComponents(): " + cm.getNumComponents());
// System.err.println("cm.getPixelSize(): " + cm.getPixelSize());
// System.err.println("cm.getComponentSize(): " + Arrays.toString(cm.getComponentSize()));
// System.err.println("sm.getNumDataElements(): " + sm.getNumDataElements());
// System.err.println("sm.getNumBands(): " + sm.getNumBands());
// System.err.println("sm.getSampleSize(): " + Arrays.toString(sm.getSampleSize()));
DataBuffer buffer = MappedFileBuffer.create(sm.getTransferType(), width * height * sm.getNumDataElements(), 1);
// DataBuffer buffer = sm.createDataBuffer();
BufferedImage image = new BufferedImage(cm, new GenericWritableRaster(sm, buffer, new Point()), cm.isAlphaPremultiplied(), null);
// BufferedImage image = new BufferedImage(cm, new SunWritableRaster(sm, buffer, new Point()), cm.isAlphaPremultiplied(), null);
// BufferedImage image = new BufferedImage(cm, Raster.createWritableRaster(sm, buffer, null), false null);
return image;
}
}