private static BufferedImage vectorGraphic( List<Float> data, RectilinearGrid rectGrid, ImageProducer ip) throws IOException { int width = ip.getPicWidth(); int height = ip.getPicHeight(); IndexColorModel cm = ip.getColorModel(); int[] rgbs = new int[cm.getMapSize()]; cm.getRGBs(rgbs); BufferedImage im = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_INDEXED, cm); Graphics2D g2d = im.createGraphics(); BoundingBox bbox = rectGrid.getExtent(); double lonDiff = bbox.getMaxX() - bbox.getMinX(); double latDiff = bbox.getMaxY() - bbox.getMinY(); // This ensures that the highest value of longitude (corresponding // with nLon - 1) is getLonMax() double lonStride = lonDiff / (width - 1); double latStride = latDiff / (height - 1); // Create the transform. We scale by the inverse of the stride length AffineTransform transform = new AffineTransform(); transform.scale(1.0 / lonStride, 1.0 / latStride); // Then we translate by the minimum coordinate values transform.translate(-bbox.getMinX(), -bbox.getMinY()); g2d.setTransform(transform); int xSize = rectGrid.getAxis(0).getSize(); int ySize = rectGrid.getAxis(1).getSize(); // Populate the BufferedImages using the information from the curvilinear grid // Iterate over all the cells in the grid, painting the i and j indices of the // cell onto the BufferedImage for (Cell cell : getCells(rectGrid)) { // Need to flip the y-axis int j = ySize - 1 - cell.j; int index = cell.i + xSize * j; Float val = data.get(index); int colourIndex = ip.getColourIndex(val); // Get a Path representing the boundary of the cell Path2D path = cell.path; g2d.setPaint(new Color(cm.getRGB(colourIndex))); g2d.fill(path); // We paint a second copy of the cell, shifted by 360 degrees, to handle // the anti-meridian // TODO: this bit increases runtime by 30% double shiftLon = cell.centre.getLongitude() > 0.0 ? -360.0 : 360.0; path.transform(AffineTransform.getTranslateInstance(shiftLon, 0.0)); g2d.fill(path); } return im; }
public ByteFilter( ByteInterleavedRaster srcRas, ColorModel cm, AffineTransform xform, int maxw) { super( (cm.getTransparency() == Transparency.OPAQUE ? xrgbmodel : argbmodel), xform, srcRas.getWidth(), srcRas.getHeight(), maxw); this.inPalette = new int[256]; ((IndexColorModel) cm).getRGBs(this.inPalette); this.srcRas = srcRas; this.inData = srcRas.getDataStorage(); this.inSpan = srcRas.getScanlineStride(); this.inOff = srcRas.getDataOffset(0); }
public void setColorModel(ColorModel model) { if (src != null) { src.checkSecurity(null, false); } srcModel = model; // Check to see if model is INT_RGB if (model instanceof IndexColorModel) { if (model.getTransparency() == model.TRANSLUCENT) { // REMIND: // Probably need to composite anyway so force ARGB cmodel = ColorModel.getRGBdefault(); srcLUT = null; } else { IndexColorModel icm = (IndexColorModel) model; numSrcLUT = icm.getMapSize(); srcLUT = new int[Math.max(numSrcLUT, 256)]; icm.getRGBs(srcLUT); srcLUTtransIndex = icm.getTransparentPixel(); cmodel = model; } } else { if (cmodel == null) { cmodel = model; srcLUT = null; } else if (model instanceof DirectColorModel) { // If it is INT_RGB or INT_ARGB, use the model DirectColorModel dcm = (DirectColorModel) model; if ((dcm.getRedMask() == 0xff0000) && (dcm.getGreenMask() == 0xff00) && (dcm.getBlueMask() == 0x00ff)) { cmodel = model; srcLUT = null; } } } isSameCM = (cmodel == model); }
public void setPixels( int x, int y, int w, int h, ColorModel model, byte pix[], int off, int scansize) { int lineOff = off; int poff; int[] newLUT = null; if (src != null) { src.checkSecurity(null, false); } // REMIND: What if the model doesn't fit in default color model? synchronized (this) { if (bimage == null) { if (cmodel == null) { cmodel = model; } createBufferedImage(); } if (w <= 0 || h <= 0) { return; } int biWidth = biRaster.getWidth(); int biHeight = biRaster.getHeight(); int x1 = x + w; // Overflow protection below int y1 = y + h; // Overflow protection below if (x < 0) { off -= x; x = 0; } else if (x1 < 0) { x1 = biWidth; // Must be overflow } if (y < 0) { off -= y * scansize; y = 0; } else if (y1 < 0) { y1 = biHeight; // Must be overflow } if (x1 > biWidth) { x1 = biWidth; } if (y1 > biHeight) { y1 = biHeight; } if (x >= x1 || y >= y1) { return; } // x,y,x1,y1 are all >= 0, so w,h must be >= 0 w = x1 - x; h = y1 - y; // off is first pixel read so it must be in bounds if (off < 0 || off >= pix.length) { // They overflowed their own array throw new ArrayIndexOutOfBoundsException("Data offset out of bounds."); } // pix.length and off are >= 0 so remainder >= 0 int remainder = pix.length - off; if (remainder < w) { // They overflowed their own array throw new ArrayIndexOutOfBoundsException("Data array is too short."); } int num; if (scansize < 0) { num = (off / -scansize) + 1; } else if (scansize > 0) { num = ((remainder - w) / scansize) + 1; } else { num = h; } if (h > num) { // They overflowed their own array. throw new ArrayIndexOutOfBoundsException("Data array is too short."); } if (isSameCM && (cmodel != model) && (srcLUT != null) && (model instanceof IndexColorModel) && (biRaster instanceof ByteComponentRaster)) { IndexColorModel icm = (IndexColorModel) model; ByteComponentRaster bct = (ByteComponentRaster) biRaster; int numlut = numSrcLUT; if (!setDiffICM( x, y, w, h, srcLUT, srcLUTtransIndex, numSrcLUT, icm, pix, off, scansize, bct, bct.getDataOffset(0))) { convertToRGB(); } else { // Note that setDiffICM modified the raster directly // so we must mark it as changed bct.markDirty(); if (numlut != numSrcLUT) { boolean hasAlpha = icm.hasAlpha(); if (srcLUTtransIndex != -1) { hasAlpha = true; } int nbits = icm.getPixelSize(); icm = new IndexColorModel( nbits, numSrcLUT, srcLUT, 0, hasAlpha, srcLUTtransIndex, (nbits > 8 ? DataBuffer.TYPE_USHORT : DataBuffer.TYPE_BYTE)); cmodel = icm; bimage = createImage(icm, bct, false, null); } return; } } if (isDefaultBI) { int pixel; IntegerComponentRaster iraster = (IntegerComponentRaster) biRaster; if (srcLUT != null && model instanceof IndexColorModel) { if (model != srcModel) { // Fill in the new lut ((IndexColorModel) model).getRGBs(srcLUT); srcModel = model; } if (s_useNative) { // Note that setICMpixels modifies the raster directly // so we must mark it as changed afterwards if (setICMpixels(x, y, w, h, srcLUT, pix, off, scansize, iraster)) { iraster.markDirty(); } else { abort(); return; } } else { int[] storage = new int[w * h]; int soff = 0; // It is an IndexColorModel for (int yoff = 0; yoff < h; yoff++, lineOff += scansize) { poff = lineOff; for (int i = 0; i < w; i++) { storage[soff++] = srcLUT[pix[poff++] & 0xff]; } } iraster.setDataElements(x, y, w, h, storage); } } else { int[] storage = new int[w]; for (int yoff = y; yoff < y + h; yoff++, lineOff += scansize) { poff = lineOff; for (int i = 0; i < w; i++) { storage[i] = model.getRGB(pix[poff++] & 0xff); } iraster.setDataElements(x, yoff, w, 1, storage); } availinfo |= ImageObserver.SOMEBITS; } } else if ((cmodel == model) && (biRaster instanceof ByteComponentRaster) && (biRaster.getNumDataElements() == 1)) { ByteComponentRaster bt = (ByteComponentRaster) biRaster; if (off == 0 && scansize == w) { bt.putByteData(x, y, w, h, pix); } else { byte[] bpix = new byte[w]; poff = off; for (int yoff = y; yoff < y + h; yoff++) { System.arraycopy(pix, poff, bpix, 0, w); bt.putByteData(x, yoff, w, 1, bpix); poff += scansize; } } } else { for (int yoff = y; yoff < y + h; yoff++, lineOff += scansize) { poff = lineOff; for (int xoff = x; xoff < x + w; xoff++) { bimage.setRGB(xoff, yoff, model.getRGB(pix[poff++] & 0xff)); } } availinfo |= ImageObserver.SOMEBITS; } } if ((availinfo & ImageObserver.FRAMEBITS) == 0) { newInfo(image, ImageObserver.SOMEBITS, x, y, w, h); } }
/* * Return the color model to be used with this BufferedImage and * transform. */ private ColorModel getTransformColorModel( SunGraphics2D sg, BufferedImage bImg, AffineTransform tx) { ColorModel cm = bImg.getColorModel(); ColorModel dstCM = cm; if (tx.isIdentity()) { return dstCM; } int type = tx.getType(); boolean needTrans = ((type & (tx.TYPE_MASK_ROTATION | tx.TYPE_GENERAL_TRANSFORM)) != 0); if (!needTrans && type != tx.TYPE_TRANSLATION && type != tx.TYPE_IDENTITY) { double[] mtx = new double[4]; tx.getMatrix(mtx); // Check out the matrix. A non-integral scale will force ARGB // since the edge conditions cannot be guaranteed. needTrans = (mtx[0] != (int) mtx[0] || mtx[3] != (int) mtx[3]); } if (sg.renderHint != SunHints.INTVAL_RENDER_QUALITY) { if (cm instanceof IndexColorModel) { Raster raster = bImg.getRaster(); IndexColorModel icm = (IndexColorModel) cm; // Just need to make sure that we have a transparent pixel if (needTrans && cm.getTransparency() == cm.OPAQUE) { // Fix 4221407 if (raster instanceof sun.awt.image.BytePackedRaster) { dstCM = ColorModel.getRGBdefault(); } else { double[] matrix = new double[6]; tx.getMatrix(matrix); if (matrix[1] == 0. && matrix[2] == 0. && matrix[4] == 0. && matrix[5] == 0.) { // Only scaling so do not need to create } else { int mapSize = icm.getMapSize(); if (mapSize < 256) { int[] cmap = new int[mapSize + 1]; icm.getRGBs(cmap); cmap[mapSize] = 0x0000; dstCM = new IndexColorModel( icm.getPixelSize(), mapSize + 1, cmap, 0, true, mapSize, DataBuffer.TYPE_BYTE); } else { dstCM = ColorModel.getRGBdefault(); } } /* if (matrix[0] < 1.f ...) */ } /* raster instanceof sun.awt.image.BytePackedRaster */ } /* if (cm.getTransparency() == cm.OPAQUE) */ } /* if (cm instanceof IndexColorModel) */ else if (needTrans && cm.getTransparency() == cm.OPAQUE) { // Need a bitmask transparency // REMIND: for now, use full transparency since no loops // for bitmask dstCM = ColorModel.getRGBdefault(); } } /* if (sg.renderHint == RENDER_QUALITY) */ else { if (cm instanceof IndexColorModel || (needTrans && cm.getTransparency() == cm.OPAQUE)) { // Need a bitmask transparency // REMIND: for now, use full transparency since no loops // for bitmask dstCM = ColorModel.getRGBdefault(); } } return dstCM; }
@Override public void glyph( final Graphics2D g, final Rectangle2D rect, final CachedDimRangeSymbolizer symbol, final MapLayer layer) { int[] ARGB = new int[] {Color.RED.getRGB(), Color.GREEN.getRGB(), Color.BLUE.getRGB()}; if (layer instanceof CoverageMapLayer) { final CoverageMapLayer cml = (CoverageMapLayer) layer; final CoverageReference ref = cml.getCoverageReference(); try { final GridCoverageReader reader = ref.acquireReader(); final GridCoverageReadParam param = new GridCoverageReadParam(); param.setResolution(1, 1); GridCoverage2D cov = (GridCoverage2D) reader.read(0, param); ref.recycle(reader); cov = cov.view(ViewType.NATIVE); RenderedImage img = cov.getRenderedImage(); ColorModel cm = img.getColorModel(); if (cm instanceof IndexColorModel) { final IndexColorModel icm = (IndexColorModel) cm; final GridSampleDimension sampleDim = cov.getSampleDimension(0); int size = icm.getMapSize(); ARGB = new int[size]; icm.getRGBs(ARGB); final double minVal = sampleDim.getMinimumValue(); final double maxVal = sampleDim.getMaximumValue(); final ColorMap colorMap = new ColorMap(); colorMap.setGeophysicsRange( ColorMap.ANY_QUANTITATIVE_CATEGORY, new MeasurementRange( NumberRange.create(minVal, true, maxVal, true), sampleDim.getUnits())); GridSampleDimension ret = colorMap.recolor(sampleDim, ARGB); } } catch (CoverageStoreException | CancellationException ex) { Logging.getLogger("org.geotoolkit.display2d.ext.dimrange").log(Level.WARNING, null, ex); } } final float[] space = new float[ARGB.length]; final Color[] colors = new Color[ARGB.length]; for (int i = 0; i < space.length; i++) { space[i] = (float) i / (space.length - 1); colors[i] = new Color(ARGB[i]); } final LinearGradientPaint paint = new LinearGradientPaint( (float) rect.getMinX(), (float) rect.getMinY(), (float) rect.getMaxX(), (float) rect.getMinY(), space, colors); g.setPaint(paint); g.fill(rect); }