// returns a value specifying some kind of average brightness in the image. protected int getAverageBrightness(BufferedImage img) { Raster r = img.getData(); int total = 0; for (int y = 0; y < r.getHeight(); y++) { for (int x = 0; x < r.getWidth(); x++) { total += r.getSample(r.getMinX() + x, r.getMinY() + y, 0); } } return (int) (total / ((r.getWidth() / factorD) * (r.getHeight() / factorD))); }
// If defaultNewIsNull is true, then newIsNull is ignored and it should behave as // if newIsNull were false. private void runTest( WritableRaster source, double sourceNoData, double newValue, boolean defaultNewIsNull, boolean newIsNull) { ColorModel cm1 = RasterUtils.createColorModel(source); java.util.Hashtable<String, Object> arg1Properties = new java.util.Hashtable<String, Object>(); arg1Properties.put(OpImageUtils.NODATA_PROPERTY, sourceNoData); BufferedImage s1 = new BufferedImage(cm1, source, false, arg1Properties); RenderedOp op = null; if (defaultNewIsNull) { op = ReplaceNullDescriptor.create(s1, newValue, null); } else { op = ReplaceNullDescriptor.create(s1, newValue, newIsNull, null); } Raster r = op.getData(); if (!defaultNewIsNull && newIsNull) { Assert.assertEquals(newValue, OpImageUtils.getNoData(op, Double.NaN), EPSILON); } else { Assert.assertTrue(Double.isNaN(OpImageUtils.getNoData(op, Double.NaN))); } Assert.assertEquals(width, r.getWidth()); Assert.assertEquals(height, r.getHeight()); for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { double v = r.getSampleDouble(x, y, 0); int pixelId = getPixelId(x, y, width); Assert.assertEquals(pixelId, v, EPSILON); } } }
private Raster clipRowToRect( final Raster raster, final Rectangle rect, final int[] bands, final int xSub) { if (rect.contains(raster.getMinX(), 0, raster.getWidth(), 1) && xSub == 1 && bands == null /* TODO: Compare bands with that of raster */) { return raster; } return raster.createChild(rect.x / xSub, 0, rect.width / xSub, 1, 0, 0, bands); }
public final Rectangle2D getBounds2D(Raster src) { // We position source raster to (0,0) even if it is translated child // raster. // This means that we need only width and height of the src int width = src.getWidth(); int height = src.getHeight(); float[] corners = {0, 0, width, 0, width, height, 0, height}; at.transform(corners, 0, corners, 0, 4); Rectangle2D.Float bounds = new Rectangle2D.Float(corners[0], corners[1], 0, 0); bounds.add(corners[2], corners[3]); bounds.add(corners[4], corners[5]); bounds.add(corners[6], corners[7]); return bounds; }
public static BufferedImage toGrayScale(BufferedImage image) { BufferedImage result = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_BYTE_GRAY); Raster raster = image.getData(); WritableRaster grayRaster = result.getRaster(); int height = raster.getHeight(); int sample = 0; for (int x = 0; x < raster.getWidth(); ++x) { for (int y = 0; y < height; ++y) { sample = raster.getSample(x, y, 0) + raster.getSample(x, y, 1) + raster.getSample(x, y, 2); grayRaster.setSample(x, y, 0, (int) ((float) sample / 3.0)); } } return result; }
/** * Paint the image onto a Graphics object. The painting is performed tile-by-tile, and includes a * grey region covering the unused portion of image tiles as well as the general background. At * this point the image must be byte data. */ public synchronized void paintComponent(Graphics g) { Graphics2D g2D = null; if (g instanceof Graphics2D) { g2D = (Graphics2D) g; } else { return; } // if source is null, it's just a component if (source == null) { g2D.setColor(getBackground()); g2D.fillRect(0, 0, componentWidth, componentHeight); return; } int transX = -originX; int transY = -originY; // Get the clipping rectangle and translate it into image coordinates. Rectangle clipBounds = g.getClipBounds(); if (clipBounds == null) { clipBounds = new Rectangle(0, 0, componentWidth, componentHeight); } // clear the background (clip it) [minimal optimization here] if (transX > 0 || transY > 0 || transX < (componentWidth - source.getWidth()) || transY < (componentHeight - source.getHeight())) { g2D.setColor(getBackground()); g2D.fillRect(0, 0, componentWidth, componentHeight); } clipBounds.translate(-transX, -transY); // Determine the extent of the clipping region in tile coordinates. int txmin, txmax, tymin, tymax; int ti, tj; txmin = XtoTileX(clipBounds.x); txmin = Math.max(txmin, minTileX); txmin = Math.min(txmin, maxTileX); txmax = XtoTileX(clipBounds.x + clipBounds.width - 1); txmax = Math.max(txmax, minTileX); txmax = Math.min(txmax, maxTileX); tymin = YtoTileY(clipBounds.y); tymin = Math.max(tymin, minTileY); tymin = Math.min(tymin, maxTileY); tymax = YtoTileY(clipBounds.y + clipBounds.height - 1); tymax = Math.max(tymax, minTileY); tymax = Math.min(tymax, maxTileY); Insets insets = getInsets(); // Loop over tiles within the clipping region for (tj = tymin; tj <= tymax; tj++) { for (ti = txmin; ti <= txmax; ti++) { int tx = TileXtoX(ti); int ty = TileYtoY(tj); Raster tile = source.getTile(ti, tj); if (tile != null) { DataBuffer dataBuffer = tile.getDataBuffer(); WritableRaster wr = tile.createWritableRaster(sampleModel, dataBuffer, null); BufferedImage bi = new BufferedImage(colorModel, wr, colorModel.isAlphaPremultiplied(), null); // correctly handles band offsets if (brightnessEnabled == true) { SampleModel sm = sampleModel.createCompatibleSampleModel(tile.getWidth(), tile.getHeight()); WritableRaster raster = RasterFactory.createWritableRaster(sm, null); BufferedImage bimg = new BufferedImage(colorModel, raster, colorModel.isAlphaPremultiplied(), null); // don't move this code ByteLookupTable lutTable = new ByteLookupTable(0, lutData); LookupOp lookup = new LookupOp(lutTable, null); lookup.filter(bi, bimg); g2D.drawImage(bimg, biop, tx + transX + insets.left, ty + transY + insets.top); } else { AffineTransform transform; transform = AffineTransform.getTranslateInstance( tx + transX + insets.left, ty + transY + insets.top); g2D.drawRenderedImage(bi, transform); } } } } }
/** * Ipp filter. * * @param src the src. * @param dst the dst. * @param imageType the image type. * @return the int. */ @SuppressWarnings("unused") private int ippFilter(Raster src, WritableRaster dst, int imageType) { int srcStride, dstStride; boolean skipChannel = false; int channels; int offsets[] = null; switch (imageType) { case BufferedImage.TYPE_INT_RGB: case BufferedImage.TYPE_INT_BGR: { channels = 4; srcStride = src.getWidth() * 4; dstStride = dst.getWidth() * 4; skipChannel = true; break; } case BufferedImage.TYPE_INT_ARGB: case BufferedImage.TYPE_INT_ARGB_PRE: case BufferedImage.TYPE_4BYTE_ABGR: case BufferedImage.TYPE_4BYTE_ABGR_PRE: { channels = 4; srcStride = src.getWidth() * 4; dstStride = dst.getWidth() * 4; break; } case BufferedImage.TYPE_BYTE_GRAY: case BufferedImage.TYPE_BYTE_INDEXED: { channels = 1; srcStride = src.getWidth(); dstStride = dst.getWidth(); break; } case BufferedImage.TYPE_3BYTE_BGR: { channels = 3; srcStride = src.getWidth() * 3; dstStride = dst.getWidth() * 3; break; } case BufferedImage.TYPE_USHORT_GRAY: // TODO - could be done in // native code? case BufferedImage.TYPE_USHORT_565_RGB: case BufferedImage.TYPE_USHORT_555_RGB: case BufferedImage.TYPE_BYTE_BINARY: { return slowFilter(src, dst); } default: { SampleModel srcSM = src.getSampleModel(); SampleModel dstSM = dst.getSampleModel(); if (srcSM instanceof PixelInterleavedSampleModel && dstSM instanceof PixelInterleavedSampleModel) { // Check PixelInterleavedSampleModel if (srcSM.getDataType() != DataBuffer.TYPE_BYTE || dstSM.getDataType() != DataBuffer.TYPE_BYTE) { return slowFilter(src, dst); } channels = srcSM.getNumBands(); // Have IPP functions for 1, // 3 and 4 channels if (channels != 1 && channels != 3 && channels != 4) { return slowFilter(src, dst); } int dataTypeSize = DataBuffer.getDataTypeSize(srcSM.getDataType()) / 8; srcStride = ((ComponentSampleModel) srcSM).getScanlineStride() * dataTypeSize; dstStride = ((ComponentSampleModel) dstSM).getScanlineStride() * dataTypeSize; } else if (srcSM instanceof SinglePixelPackedSampleModel && dstSM instanceof SinglePixelPackedSampleModel) { // Check SinglePixelPackedSampleModel SinglePixelPackedSampleModel sppsm1 = (SinglePixelPackedSampleModel) srcSM; SinglePixelPackedSampleModel sppsm2 = (SinglePixelPackedSampleModel) dstSM; // No IPP function for this type if (sppsm1.getDataType() == DataBuffer.TYPE_USHORT) { return slowFilter(src, dst); } channels = sppsm1.getNumBands(); // Have IPP functions for 1, 3 and 4 channels if (channels != 1 && channels != 3 && channels != 4) { return slowFilter(src, dst); } // Check compatibility of sample models if (sppsm1.getDataType() != sppsm2.getDataType() || !Arrays.equals(sppsm1.getBitOffsets(), sppsm2.getBitOffsets()) || !Arrays.equals(sppsm1.getBitMasks(), sppsm2.getBitMasks())) { return slowFilter(src, dst); } for (int i = 0; i < channels; i++) { if (sppsm1.getSampleSize(i) != 8) { return slowFilter(src, dst); } } if (channels == 3) { channels = 4; } int dataTypeSize = DataBuffer.getDataTypeSize(sppsm1.getDataType()) / 8; srcStride = sppsm1.getScanlineStride() * dataTypeSize; dstStride = sppsm2.getScanlineStride() * dataTypeSize; } else { return slowFilter(src, dst); } // Fill offsets if there's a child raster if (src.getParent() != null || dst.getParent() != null) { if (src.getSampleModelTranslateX() != 0 || src.getSampleModelTranslateY() != 0 || dst.getSampleModelTranslateX() != 0 || dst.getSampleModelTranslateY() != 0) { offsets = new int[4]; offsets[0] = -src.getSampleModelTranslateX() + src.getMinX(); offsets[1] = -src.getSampleModelTranslateY() + src.getMinY(); offsets[2] = -dst.getSampleModelTranslateX() + dst.getMinX(); offsets[3] = -dst.getSampleModelTranslateY() + dst.getMinY(); } } } } double m00 = at.getScaleX(); double m01 = at.getShearX(); double m02 = at.getTranslateX(); double m10 = at.getShearY(); double m11 = at.getScaleY(); double m12 = at.getTranslateY(); Object srcData, dstData; AwtImageBackdoorAccessor dbAccess = AwtImageBackdoorAccessor.getInstance(); try { srcData = dbAccess.getData(src.getDataBuffer()); dstData = dbAccess.getData(dst.getDataBuffer()); } catch (IllegalArgumentException e) { return -1; // Unknown data buffer type } return ippAffineTransform( m00, m01, m02, m10, m11, m12, srcData, src.getWidth(), src.getHeight(), srcStride, dstData, dst.getWidth(), dst.getHeight(), dstStride, iType, channels, skipChannel, offsets); }
@Override public BufferedImage read(final int imageIndex, final ImageReadParam param) throws IOException { Iterator<ImageTypeSpecifier> imageTypes = getImageTypes(imageIndex); ImageTypeSpecifier rawType = getRawImageType(imageIndex); if (header.getPaletteInfo() != PCX.PALETTEINFO_COLOR && header.getPaletteInfo() != PCX.PALETTEINFO_GRAY) { processWarningOccurred( String.format( "Unsupported color mode: %d, colors may look incorrect", header.getPaletteInfo())); } int width = getWidth(imageIndex); int height = getHeight(imageIndex); BufferedImage destination = getDestination(param, imageTypes, width, height); Rectangle srcRegion = new Rectangle(); Rectangle destRegion = new Rectangle(); computeRegions(param, width, height, destination, srcRegion, destRegion); WritableRaster destRaster = clipToRect( destination.getRaster(), destRegion, param != null ? param.getDestinationBands() : null); checkReadParamBandSettings(param, rawType.getNumBands(), destRaster.getNumBands()); int compression = header.getCompression(); // Wrap input (COMPRESSION_RLE is really the only value allowed) DataInput input = compression == PCX.COMPRESSION_RLE ? new DataInputStream( new DecoderStream(IIOUtil.createStreamAdapter(imageInput), new RLEDecoder())) : imageInput; int xSub = param != null ? param.getSourceXSubsampling() : 1; int ySub = param != null ? param.getSourceYSubsampling() : 1; processImageStarted(imageIndex); if (rawType.getColorModel() instanceof IndexColorModel && header.getChannels() > 1) { // Bit planes! // Create raster from a default 8 bit layout WritableRaster rowRaster = GRAYSCALE.createBufferedImage(header.getWidth(), 1).getRaster(); // Clip to source region Raster clippedRow = clipRowToRect( rowRaster, srcRegion, param != null ? param.getSourceBands() : null, param != null ? param.getSourceXSubsampling() : 1); int planeWidth = header.getBytesPerLine(); byte[] planeData = new byte[planeWidth * 8]; byte[] rowDataByte = ((DataBufferByte) rowRaster.getDataBuffer()).getData(); for (int y = 0; y < height; y++) { switch (header.getBitsPerPixel()) { case 1: readRowByte( input, srcRegion, xSub, ySub, planeData, 0, planeWidth * header.getChannels(), destRaster, clippedRow, y); break; default: throw new AssertionError(); } int pixelPos = 0; for (int planePos = 0; planePos < planeWidth; planePos++) { BitRotator.bitRotateCW(planeData, planePos, planeWidth, rowDataByte, pixelPos, 1); pixelPos += 8; } processImageProgress(100f * y / height); if (y >= srcRegion.y + srcRegion.height) { break; } if (abortRequested()) { processReadAborted(); break; } } } else if (header.getBitsPerPixel() == 24 || header.getBitsPerPixel() == 32) { // Can't use width here, as we need to take bytesPerLine into account, and re-create a width // based on this int rowWidth = (header.getBytesPerLine() * 8) / header.getBitsPerPixel(); WritableRaster rowRaster = rawType.createBufferedImage(rowWidth, 1).getRaster(); // Clip to source region Raster clippedRow = clipRowToRect( rowRaster, srcRegion, param != null ? param.getSourceBands() : null, param != null ? param.getSourceXSubsampling() : 1); for (int y = 0; y < height; y++) { byte[] rowDataByte = ((DataBufferByte) rowRaster.getDataBuffer()).getData(); readRowByte( input, srcRegion, xSub, ySub, rowDataByte, 0, rowDataByte.length, destRaster, clippedRow, y); processImageProgress(100f * y / height); if (y >= srcRegion.y + srcRegion.height) { break; } if (abortRequested()) { processReadAborted(); break; } } } else { // Can't use width here, as we need to take bytesPerLine into account, and re-create a width // based on this int rowWidth = (header.getBytesPerLine() * 8) / header.getBitsPerPixel(); WritableRaster rowRaster = rawType.createBufferedImage(rowWidth, 1).getRaster(); // Clip to source region Raster clippedRow = clipRowToRect( rowRaster, srcRegion, param != null ? param.getSourceBands() : null, param != null ? param.getSourceXSubsampling() : 1); for (int y = 0; y < height; y++) { for (int c = 0; c < header.getChannels(); c++) { WritableRaster destChannel = destRaster.createWritableChild( destRaster.getMinX(), destRaster.getMinY(), destRaster.getWidth(), destRaster.getHeight(), 0, 0, new int[] {c}); Raster srcChannel = clippedRow.createChild( clippedRow.getMinX(), 0, clippedRow.getWidth(), 1, 0, 0, new int[] {c}); switch (header.getBitsPerPixel()) { case 1: case 2: case 4: case 8: byte[] rowDataByte = ((DataBufferByte) rowRaster.getDataBuffer()).getData(c); readRowByte( input, srcRegion, xSub, ySub, rowDataByte, 0, rowDataByte.length, destChannel, srcChannel, y); break; default: throw new AssertionError(); } if (abortRequested()) { break; } } processImageProgress(100f * y / height); if (y >= srcRegion.y + srcRegion.height) { break; } if (abortRequested()) { processReadAborted(); break; } } } processImageComplete(); return destination; }