public static BufferedImage convertImageData(ImageData data) { BufferedImage bimg = null; int height = data.getHeight(), width = data.getWidth(); Object pixels = data.getData(); if (pixels instanceof int[] && data.getElementWidth() == 1) { int[] arr = (int[]) pixels; byte[] barray = new byte[arr.length * 3]; int k = 0; for (int j = 0; j < arr.length; j++) { int l = arr[j]; barray[k++] = (byte) (l & 0xFF); barray[k++] = (byte) ((l >>> 8) & 0xFF); barray[k++] = (byte) ((l >>> 16) & 0xFF); } ColorModel ccm = new ComponentColorModel( ICC_ColorSpace.getInstance(ICC_ColorSpace.CS_sRGB), new int[] {8, 8, 8}, false, false, Transparency.OPAQUE, DataBuffer.TYPE_BYTE); DataBuffer bbuf = new DataBufferByte(barray, barray.length); SampleModel bmodel = new PixelInterleavedSampleModel( DataBuffer.TYPE_BYTE, width, height, 3, 3 * width, new int[] {2, 1, 0}); WritableRaster raster = Raster.createWritableRaster(bmodel, bbuf, new Point(0, 0)); bimg = new BufferedImage(ccm, raster, false, new Hashtable()); } else if (pixels instanceof byte[] && data.getElementWidth() == 1) { // Assume gray scale model? byte[] arr = (byte[]) pixels; byte[] barray = new byte[arr.length * 3]; int k = 0; for (int j = 0; j < arr.length; j++) { byte l = arr[j]; barray[k++] = l; barray[k++] = l; barray[k++] = l; } ColorModel ccm = new ComponentColorModel( ICC_ColorSpace.getInstance(ICC_ColorSpace.CS_sRGB), new int[] {8, 8, 8}, false, false, Transparency.OPAQUE, DataBuffer.TYPE_BYTE); DataBuffer bbuf = new DataBufferByte(barray, barray.length); SampleModel bmodel = new PixelInterleavedSampleModel( DataBuffer.TYPE_BYTE, width, height, 3, 3 * width, new int[] {2, 1, 0}); WritableRaster raster = Raster.createWritableRaster(bmodel, bbuf, new Point(0, 0)); bimg = new BufferedImage(ccm, raster, false, new Hashtable()); } else { throw new RuntimeException("Unexpected data."); } return bimg; }
private void writeGrayscaleImage(BufferedImage image, AVList params) throws IOException { int type = image.getType(); int bitsPerSample = (BufferedImage.TYPE_USHORT_GRAY == type) ? Tiff.BitsPerSample.MONOCHROME_UINT16 : Tiff.BitsPerSample.MONOCHROME_UINT8; int numBands = image.getSampleModel().getNumBands(); // well, numBands for GrayScale images must be 1 int bytesPerSample = numBands * bitsPerSample / Byte.SIZE; this.writeTiffHeader(); // write the image data... int numRows = image.getHeight(); int numCols = image.getWidth(); int[] stripCounts = new int[numRows]; int[] stripOffsets = new int[numRows]; ByteBuffer dataBuff = ByteBuffer.allocateDirect(numCols * bytesPerSample); Raster rast = image.getRaster(); for (int i = 0; i < numRows; i++) { stripOffsets[i] = (int) this.theChannel.position(); stripCounts[i] = numCols * bytesPerSample; int[] rowData = rast.getPixels(0, i, image.getWidth(), 1, (int[]) null); dataBuff.clear(); if (BufferedImage.TYPE_USHORT_GRAY == type) { for (int j = 0; j < numCols * numBands; j++) { this.putUnsignedShort(dataBuff, rowData[j]); } } else if (BufferedImage.TYPE_BYTE_GRAY == type) { for (int j = 0; j < numCols * numBands; j++) { this.putUnsignedByte(dataBuff, rowData[j]); } } dataBuff.flip(); this.theChannel.write(dataBuff); } // write out values for the tiff tags and build up the IFD. These are supposed to be sorted; for // now // do this manually here. ArrayList<TiffIFDEntry> ifds = new ArrayList<TiffIFDEntry>(10); ifds.add(new TiffIFDEntry(Tiff.Tag.IMAGE_WIDTH, Tiff.Type.LONG, 1, numCols)); ifds.add(new TiffIFDEntry(Tiff.Tag.IMAGE_LENGTH, Tiff.Type.LONG, 1, numRows)); ifds.add(new TiffIFDEntry(Tiff.Tag.BITS_PER_SAMPLE, Tiff.Type.SHORT, 1, bitsPerSample)); ifds.add(new TiffIFDEntry(Tiff.Tag.COMPRESSION, Tiff.Type.LONG, 1, Tiff.Compression.NONE)); ifds.add( new TiffIFDEntry( Tiff.Tag.PHOTO_INTERPRETATION, Tiff.Type.SHORT, 1, Tiff.Photometric.Grayscale_BlackIsZero)); ifds.add( new TiffIFDEntry(Tiff.Tag.SAMPLE_FORMAT, Tiff.Type.SHORT, 1, Tiff.SampleFormat.UNSIGNED)); long offset = this.theChannel.position(); dataBuff = ByteBuffer.allocateDirect(stripOffsets.length * INTEGER_SIZEOF); for (int stripOffset : stripOffsets) { dataBuff.putInt(stripOffset); } dataBuff.flip(); this.theChannel.write(dataBuff); ifds.add(new TiffIFDEntry(Tiff.Tag.STRIP_OFFSETS, Tiff.Type.LONG, stripOffsets.length, offset)); ifds.add(new TiffIFDEntry(Tiff.Tag.SAMPLES_PER_PIXEL, Tiff.Type.SHORT, 1, numBands)); ifds.add(new TiffIFDEntry(Tiff.Tag.ROWS_PER_STRIP, Tiff.Type.LONG, 1, 1)); offset = this.theChannel.position(); dataBuff.clear(); // stripOffsets and stripCounts are same length by design; can reuse the // ByteBuffer... for (int stripCount : stripCounts) { dataBuff.putInt(stripCount); } dataBuff.flip(); this.theChannel.write(dataBuff); ifds.add( new TiffIFDEntry(Tiff.Tag.STRIP_BYTE_COUNTS, Tiff.Type.LONG, stripCounts.length, offset)); this.appendGeoTiff(ifds, params); this.writeIFDs(ifds); }
/** Convert standard img to a buffered image. */ public static BufferedImage convertImage(Image img) { int height = img.getHeight(null), width = img.getWidth(null); // FloatMatrix fm = new FloatMatrix( height, width ) ; PixelGrabber grabber = new PixelGrabber(img, 0, 0, width, height, false); try { grabber.grabPixels(); } catch (InterruptedException e) { System.out.println(e); } Object pixels = grabber.getPixels(); ColorModel cm = grabber.getColorModel(); BufferedImage bimg = null; // REVISIT Makes some unwarranted assumptions about the layout of the PixelGrabber data // as being either int (ARGB?) or byte (gray scale?) if (pixels instanceof int[]) { int[] arr = (int[]) pixels; byte[] barray = new byte[arr.length * 3]; int k = 0; for (int j = 0; j < arr.length; j++) { int l = arr[j]; barray[k++] = (byte) (l & 0xFF); barray[k++] = (byte) ((l >>> 8) & 0xFF); barray[k++] = (byte) ((l >>> 16) & 0xFF); } ColorModel ccm = new ComponentColorModel( ICC_ColorSpace.getInstance(ICC_ColorSpace.CS_sRGB), new int[] {8, 8, 8}, false, false, Transparency.OPAQUE, DataBuffer.TYPE_BYTE); DataBuffer bbuf = new DataBufferByte(barray, barray.length); SampleModel bmodel = new PixelInterleavedSampleModel( DataBuffer.TYPE_BYTE, width, height, 3, 3 * width, new int[] {2, 1, 0}); WritableRaster raster = Raster.createWritableRaster(bmodel, bbuf, new Point(0, 0)); bimg = new BufferedImage(ccm, raster, false, new Hashtable()); } else if (pixels instanceof byte[]) { // Assume gray scale model? byte[] arr = (byte[]) pixels; byte[] barray = new byte[arr.length * 3]; int k = 0; for (int j = 0; j < arr.length; j++) { byte l = arr[j]; barray[k++] = l; barray[k++] = l; barray[k++] = l; } ColorModel ccm = new ComponentColorModel( ICC_ColorSpace.getInstance(ICC_ColorSpace.CS_sRGB), new int[] {8, 8, 8}, false, false, Transparency.OPAQUE, DataBuffer.TYPE_BYTE); DataBuffer bbuf = new DataBufferByte(barray, barray.length); SampleModel bmodel = new PixelInterleavedSampleModel( DataBuffer.TYPE_BYTE, width, height, 3, 3 * width, new int[] {2, 1, 0}); WritableRaster raster = Raster.createWritableRaster(bmodel, bbuf, new Point(0, 0)); bimg = new BufferedImage(ccm, raster, false, new Hashtable()); } else { throw new RuntimeException("Unexpected data."); } return bimg; }
private void writeColorImage(BufferedImage image, AVList params) throws IOException { int numBands = image.getRaster().getNumBands(); long offset; this.writeTiffHeader(); // write the image data... int numRows = image.getHeight(); int numCols = image.getWidth(); int[] stripCounts = new int[numRows]; int[] stripOffsets = new int[numRows]; ByteBuffer dataBuff = ByteBuffer.allocateDirect(numCols * numBands); Raster rast = image.getRaster(); for (int i = 0; i < numRows; i++) { stripOffsets[i] = (int) this.theChannel.position(); stripCounts[i] = numCols * numBands; int[] rowData = rast.getPixels(0, i, image.getWidth(), 1, (int[]) null); dataBuff.clear(); for (int j = 0; j < numCols * numBands; j++) { putUnsignedByte(dataBuff, rowData[j]); } dataBuff.flip(); this.theChannel.write(dataBuff); } // write out values for the tiff tags and build up the IFD. These are supposed to be sorted; for // now // do this manually here. ArrayList<TiffIFDEntry> ifds = new ArrayList<TiffIFDEntry>(10); ifds.add(new TiffIFDEntry(Tiff.Tag.IMAGE_WIDTH, Tiff.Type.LONG, 1, numCols)); ifds.add(new TiffIFDEntry(Tiff.Tag.IMAGE_LENGTH, Tiff.Type.LONG, 1, numRows)); ifds.add( new TiffIFDEntry( Tiff.Tag.PLANAR_CONFIGURATION, Tiff.Type.SHORT, 1, Tiff.PlanarConfiguration.CHUNKY)); ifds.add(new TiffIFDEntry(Tiff.Tag.SAMPLES_PER_PIXEL, Tiff.Type.SHORT, 1, numBands)); ifds.add(new TiffIFDEntry(Tiff.Tag.COMPRESSION, Tiff.Type.LONG, 1, Tiff.Compression.NONE)); ifds.add( new TiffIFDEntry( Tiff.Tag.PHOTO_INTERPRETATION, Tiff.Type.SHORT, 1, Tiff.Photometric.Color_RGB)); ifds.add(new TiffIFDEntry(Tiff.Tag.ORIENTATION, Tiff.Type.SHORT, 1, Tiff.Orientation.DEFAULT)); offset = this.theChannel.position(); short[] bps = new short[numBands]; for (int i = 0; i < numBands; i++) { bps[i] = Tiff.BitsPerSample.MONOCHROME_BYTE; } this.theChannel.write(ByteBuffer.wrap(this.getBytes(bps))); ifds.add(new TiffIFDEntry(Tiff.Tag.BITS_PER_SAMPLE, Tiff.Type.SHORT, numBands, offset)); offset = this.theChannel.position(); dataBuff = ByteBuffer.allocateDirect(stripOffsets.length * INTEGER_SIZEOF); for (int stripOffset : stripOffsets) { dataBuff.putInt(stripOffset); } dataBuff.flip(); this.theChannel.write(dataBuff); ifds.add(new TiffIFDEntry(Tiff.Tag.STRIP_OFFSETS, Tiff.Type.LONG, stripOffsets.length, offset)); ifds.add(new TiffIFDEntry(Tiff.Tag.ROWS_PER_STRIP, Tiff.Type.LONG, 1, 1)); offset = this.theChannel.position(); dataBuff.clear(); // stripOffsets and stripCounts are same length by design; can reuse the ByteBuffer... for (int stripCount : stripCounts) { dataBuff.putInt(stripCount); } dataBuff.flip(); this.theChannel.write(dataBuff); ifds.add( new TiffIFDEntry(Tiff.Tag.STRIP_BYTE_COUNTS, Tiff.Type.LONG, stripCounts.length, offset)); this.appendGeoTiff(ifds, params); this.writeIFDs(ifds); }