Search in sources :

Example 1 with PngWriter

use of ar.com.hjg.pngj.PngWriter in project xDrip by NightscoutFoundation.

the class SimpleImageEncoder method encodeIndexedPNG.

public byte[] encodeIndexedPNG(int[] pixels, int width, int height, boolean color, int bits) {
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    int[] palette = getPalette();
    boolean alpha = Color.alpha(palette[0]) == 0;
    boolean grayscale = !color;
    // Log.d(TAG, "encodeIndexedPNG: color = "+color +", alpha ="+alpha+", grayscale = "+grayscale);
    // ImageInfo imageInfo = new ImageInfo(width, height, bits, alpha, grayscale, color);
    ImageInfo imageInfo = new ImageInfo(width, height, bits, false, grayscale, color);
    PngWriter writer = new PngWriter(bos, imageInfo);
    writer.getPixelsWriter().setDeflaterCompLevel(9);
    if (color) {
        PngChunkPLTE paletteChunk = writer.getMetadata().createPLTEChunk();
        paletteChunk.setNentries(palette.length);
        for (int i = 0; i < palette.length; i++) {
            int c = palette[i];
            paletteChunk.setEntry(i, Color.red(c), Color.green(c), Color.blue(c));
        }
    }
    if (alpha) {
        PngChunkTRNS trnsChunk = writer.getMetadata().createTRNSChunk();
        if (color) {
            trnsChunk.setIndexEntryAsTransparent(0);
        } else {
            trnsChunk.setGray(1);
        }
    } else {
        quantize(pixels, imageInfo.cols);
    }
    ImageLineInt line = new ImageLineInt(imageInfo);
    for (int y = 0; y < imageInfo.rows; y++) {
        int[] lineData = line.getScanline();
        for (int x = 0; x < imageInfo.cols; x++) {
            int pixel = pixels[y * imageInfo.cols + x];
            // lineData[x] = getNearestColorIndex(pixel) ^ (x % 2) ^ (y % 2);
            lineData[x] = getNearestColorIndex(pixel);
        }
        writer.writeRow(line);
    }
    writer.end();
    return bos.toByteArray();
}
Also used : PngChunkTRNS(ar.com.hjg.pngj.chunks.PngChunkTRNS) ByteArrayOutputStream(java.io.ByteArrayOutputStream) ImageInfo(ar.com.hjg.pngj.ImageInfo) PngChunkPLTE(ar.com.hjg.pngj.chunks.PngChunkPLTE) PngWriter(ar.com.hjg.pngj.PngWriter) ImageLineInt(ar.com.hjg.pngj.ImageLineInt)

Example 2 with PngWriter

use of ar.com.hjg.pngj.PngWriter in project xDrip-plus by jamorham.

the class SimpleImageEncoder method encodeIndexedPNG.

public byte[] encodeIndexedPNG(int[] pixels, int width, int height, boolean color, int bits) {
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    int[] palette = getPalette();
    boolean alpha = Color.alpha(palette[0]) == 0;
    boolean grayscale = !color;
    // Log.d(TAG, "encodeIndexedPNG: color = "+color +", alpha ="+alpha+", grayscale = "+grayscale);
    // ImageInfo imageInfo = new ImageInfo(width, height, bits, alpha, grayscale, color);
    ImageInfo imageInfo = new ImageInfo(width, height, bits, false, grayscale, color);
    PngWriter writer = new PngWriter(bos, imageInfo);
    writer.getPixelsWriter().setDeflaterCompLevel(9);
    if (color) {
        PngChunkPLTE paletteChunk = writer.getMetadata().createPLTEChunk();
        paletteChunk.setNentries(palette.length);
        for (int i = 0; i < palette.length; i++) {
            int c = palette[i];
            paletteChunk.setEntry(i, Color.red(c), Color.green(c), Color.blue(c));
        }
    }
    if (alpha) {
        PngChunkTRNS trnsChunk = writer.getMetadata().createTRNSChunk();
        if (color) {
            trnsChunk.setIndexEntryAsTransparent(0);
        } else {
            trnsChunk.setGray(1);
        }
    } else {
        quantize(pixels, imageInfo.cols);
    }
    ImageLineInt line = new ImageLineInt(imageInfo);
    for (int y = 0; y < imageInfo.rows; y++) {
        int[] lineData = line.getScanline();
        for (int x = 0; x < imageInfo.cols; x++) {
            int pixel = pixels[y * imageInfo.cols + x];
            // lineData[x] = getNearestColorIndex(pixel) ^ (x % 2) ^ (y % 2);
            lineData[x] = getNearestColorIndex(pixel);
        }
        writer.writeRow(line);
    }
    writer.end();
    return bos.toByteArray();
}
Also used : PngChunkTRNS(ar.com.hjg.pngj.chunks.PngChunkTRNS) ByteArrayOutputStream(java.io.ByteArrayOutputStream) ImageInfo(ar.com.hjg.pngj.ImageInfo) PngChunkPLTE(ar.com.hjg.pngj.chunks.PngChunkPLTE) PngWriter(ar.com.hjg.pngj.PngWriter) ImageLineInt(ar.com.hjg.pngj.ImageLineInt)

Example 3 with PngWriter

use of ar.com.hjg.pngj.PngWriter in project OpenTripPlanner by opentripplanner.

the class TimeGridWs method getTimeGridPng.

@GET
@Produces({ "image/png" })
public Response getTimeGridPng(@QueryParam("base64") @DefaultValue("false") boolean base64) throws Exception {
    /* Fetch the Router for this request using server and routerId fields from superclass. */
    Router router = otpServer.getRouter(routerId);
    if (precisionMeters < 10)
        throw new IllegalArgumentException("Too small precisionMeters: " + precisionMeters);
    if (offRoadDistanceMeters < 10)
        throw new IllegalArgumentException("Too small offRoadDistanceMeters: " + offRoadDistanceMeters);
    // Build the request
    RoutingRequest sptRequest = buildRequest();
    SampleGridRequest tgRequest = new SampleGridRequest();
    tgRequest.maxTimeSec = maxTimeSec;
    tgRequest.precisionMeters = precisionMeters;
    tgRequest.offRoadDistanceMeters = offRoadDistanceMeters;
    if (coordinateOrigin != null)
        tgRequest.coordinateOrigin = new GenericLocation(null, coordinateOrigin).getCoordinate();
    // Get a sample grid
    ZSampleGrid<WTWD> sampleGrid = router.sampleGridRenderer.getSampleGrid(tgRequest, sptRequest);
    int cols = sampleGrid.getXMax() - sampleGrid.getXMin() + 1;
    int rows = sampleGrid.getYMax() - sampleGrid.getYMin() + 1;
    // Hard-coded to RGBA
    int channels = 4;
    // We force to 8 bits channel depth, some clients won't support more than 8
    // (namely, HTML5 canvas...)
    ImageInfo imgInfo = new ImageInfo(cols, rows, 8, true, false, false);
    /**
     * TODO: PNGJ allow for progressive (ie line-by-line) writing. Thus we could theorically
     * prevent having to allocate a bit pixel array in the first place, but we would need a
     * line-by-line iterator on the sample grid, which is currently not the case.
     */
    int[][] rgba = new int[rows][cols * channels];
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    PngWriter pw = new PngWriter(baos, imgInfo);
    pw.getMetadata().setText(PngChunkTextVar.KEY_Software, "OTPA");
    pw.getMetadata().setText(PngChunkTextVar.KEY_Creation_Time, new Date().toString());
    pw.getMetadata().setText(PngChunkTextVar.KEY_Description, "Sample grid bitmap");
    String gridCornerStr = String.format(Locale.US, "%.8f,%.8f", sampleGrid.getCenter().y + sampleGrid.getYMin() * sampleGrid.getCellSize().y, sampleGrid.getCenter().x + sampleGrid.getXMin() * sampleGrid.getCellSize().x);
    String gridCellSzStr = String.format(Locale.US, "%.12f,%.12f", sampleGrid.getCellSize().y, sampleGrid.getCellSize().x);
    String offRoadDistStr = String.format(Locale.US, "%d", offRoadDistanceMeters);
    PngChunkTEXT gridCornerChunk = new PngChunkTEXT(imgInfo);
    gridCornerChunk.setKeyVal(OTPA_GRID_CORNER, gridCornerStr);
    pw.getChunksList().queue(gridCornerChunk);
    PngChunkTEXT gridCellSzChunk = new PngChunkTEXT(imgInfo);
    gridCellSzChunk.setKeyVal(OTPA_GRID_CELL_SIZE, gridCellSzStr);
    pw.getChunksList().queue(gridCellSzChunk);
    PngChunkTEXT offRoadDistChunk = new PngChunkTEXT(imgInfo);
    offRoadDistChunk.setKeyVal(OTPA_OFFROAD_DIST, offRoadDistStr);
    pw.getChunksList().queue(offRoadDistChunk);
    double unit;
    switch(zDataType) {
        case TIME:
            // 1:1sec, max 18h
            unit = 1.0;
            break;
        case BOARDINGS:
            // 1:0.001 boarding, max 65.5
            unit = 1000.0;
            break;
        case WALK_DISTANCE:
            // 1:0.1m, max 6.55km
            unit = 10.0;
            break;
        default:
            throw new IllegalArgumentException("Unsupported Z DataType.");
    }
    for (ZSamplePoint<WTWD> p : sampleGrid) {
        WTWD z = p.getZ();
        int row = p.getY() - sampleGrid.getYMin();
        int col = p.getX() - sampleGrid.getXMin();
        double zz;
        switch(zDataType) {
            case TIME:
                zz = z.wTime / z.w;
                break;
            case BOARDINGS:
                zz = z.wBoardings / z.w;
                break;
            case WALK_DISTANCE:
                zz = z.wWalkDist / z.w;
                break;
            default:
                throw new IllegalArgumentException("Unsupported Z DataType.");
        }
        int iz;
        if (Double.isInfinite(zz)) {
            iz = 65535;
        } else {
            iz = ImageLineHelper.clampTo_0_65535((int) Math.round(zz * unit));
            if (iz == 65535)
                // Clamp
                iz = 65534;
        }
        // d is expressed as a percentage of grid size, max 255%.
        // Sometimes d will be bigger than 2.55 x grid size,
        // but this should not be too much important as we are off-bounds.
        int id = ImageLineHelper.clampTo_0_255((int) Math.round(z.d / precisionMeters * 100));
        int offset = col * channels;
        // z low 8 bits
        rgba[row][offset + 0] = (iz & 0xFF);
        // z high 8 bits
        rgba[row][offset + 1] = (iz >> 8);
        // d
        rgba[row][offset + 2] = id;
        /*
             * Keep the alpha channel at 255, otherwise the RGB channel will be downsampled on some
             * rendering clients (namely, JS canvas).
             */
        rgba[row][offset + 3] = 255;
    }
    for (int row = 0; row < rgba.length; row++) {
        ImageLineInt iline = new ImageLineInt(imgInfo, rgba[row]);
        pw.writeRow(iline, row);
    }
    pw.end();
    // Disallow caching on client side
    CacheControl cc = new CacheControl();
    cc.setNoCache(true);
    // Also put the meta-data in the HTML header (easier to read from JS)
    byte[] data = baos.toByteArray();
    if (base64) {
        data = Base64.encodeBase64(data);
    }
    return Response.ok().cacheControl(cc).entity(data).header(OTPA_GRID_CORNER, gridCornerStr).header(OTPA_GRID_CELL_SIZE, gridCellSzStr).header(OTPA_OFFROAD_DIST, offRoadDistStr).build();
}
Also used : PngChunkTEXT(ar.com.hjg.pngj.chunks.PngChunkTEXT) WTWD(org.opentripplanner.analyst.request.SampleGridRenderer.WTWD) SampleGridRequest(org.opentripplanner.analyst.request.SampleGridRequest) Router(org.opentripplanner.standalone.Router) ByteArrayOutputStream(java.io.ByteArrayOutputStream) ZSamplePoint(org.opentripplanner.common.geometry.ZSampleGrid.ZSamplePoint) Date(java.util.Date) PngWriter(ar.com.hjg.pngj.PngWriter) GenericLocation(org.opentripplanner.common.model.GenericLocation) RoutingRequest(org.opentripplanner.routing.core.RoutingRequest) CacheControl(javax.ws.rs.core.CacheControl) ImageInfo(ar.com.hjg.pngj.ImageInfo) ImageLineInt(ar.com.hjg.pngj.ImageLineInt)

Example 4 with PngWriter

use of ar.com.hjg.pngj.PngWriter in project BiomeTweaker by superckl.

the class BiomePainter method paintImage.

public void paintImage(final int radius, final ChunkPos center, final File outputFile, final GuiGeneratingBiomeLayoutImage gui) {
    Arrays.fill(this.colorArray, -1);
    final ImageInfo iInfo = new ImageInfo(radius * 2, radius * 2, 8, false);
    final IImageLineFactory<ImageLineInt> factory = ImageLineInt.getFactory(iInfo);
    final PngWriter writer = new PngWriter(outputFile, iInfo);
    final int[] colors = new int[iInfo.cols];
    final int currentX = center.x - iInfo.cols / 2;
    final int currentY = center.z + iInfo.rows / 2;
    for (int i = 0; i < iInfo.rows; i++) {
        gui.setCurrentX(currentX + i);
        for (int j = 0; j < colors.length; j++) {
            gui.setCurrentY(currentY + j);
            colors[j] = this.getColor(currentX + i, currentY + j);
        }
        final ImageLineInt line = factory.createImageLine(iInfo);
        ImageLineHelper.setPixelsRGB8(line, colors);
        writer.writeRow(line);
        gui.setProgress(((double) i) / iInfo.rows);
    }
    writer.end();
    gui.setFinished();
}
Also used : ImageInfo(ar.com.hjg.pngj.ImageInfo) ImageLineInt(ar.com.hjg.pngj.ImageLineInt) PngWriter(ar.com.hjg.pngj.PngWriter)

Example 5 with PngWriter

use of ar.com.hjg.pngj.PngWriter in project imageio-ext by geosolutions-it.

the class PNGWriter method writePNG.

public RenderedImage writePNG(RenderedImage image, OutputStream outStream, float quality, FilterType filterType, Map<String, String> text) throws Exception {
    // compute the compression level similarly to what the Clib code does
    int level = Math.round(9 * (1f - quality));
    // get the optimal scanline provider for this image
    RenderedImage original = image;
    ScanlineProvider scanlines = ScanlineProviderFactory.getProvider(image);
    if (scanlines == null) {
        throw new IllegalArgumentException("Could not find a scanline extractor for " + original);
    }
    // encode using the PNGJ library and the GeoServer own scanline providers
    ColorModel colorModel = image.getColorModel();
    boolean indexed = colorModel instanceof IndexColorModel;
    ImageInfo ii = getImageInfo(image, scanlines, colorModel, indexed);
    PngWriter pw = new PngWriter(outStream, ii);
    pw.setShouldCloseStream(false);
    try {
        pw.setCompLevel(level);
        pw.setFilterType(filterType);
        ChunksListForWrite chunkList = pw.getChunksList();
        PngMetadata metadata = pw.getMetadata();
        if (indexed) {
            IndexColorModel icm = (IndexColorModel) colorModel;
            PngChunkPLTE palette = metadata.createPLTEChunk();
            int ncolors = icm.getMapSize();
            palette.setNentries(ncolors);
            for (int i = 0; i < ncolors; i++) {
                final int red = icm.getRed(i);
                final int green = icm.getGreen(i);
                final int blue = icm.getBlue(i);
                palette.setEntry(i, red, green, blue);
            }
            if (icm.hasAlpha()) {
                PngChunkTRNS transparent = new PngChunkTRNS(ii);
                int[] alpha = new int[ncolors];
                for (int i = 0; i < ncolors; i++) {
                    final int a = icm.getAlpha(i);
                    alpha[i] = a;
                }
                transparent.setPalletteAlpha(alpha);
                chunkList.queue(transparent);
            }
        }
        if (text != null && !text.isEmpty()) {
            Iterator<Entry<String, String>> entrySetIterator = text.entrySet().iterator();
            while (entrySetIterator.hasNext()) {
                Entry<String, String> entrySet = entrySetIterator.next();
                metadata.setText(entrySet.getKey(), entrySet.getValue(), true, false);
            }
        }
        // write out the actual image lines
        for (int row = 0; row < image.getHeight(); row++) {
            pw.writeRow(scanlines);
        }
        pw.end();
    } catch (Exception e) {
        LOGGER.log(Level.SEVERE, "Failed to encode the PNG", e);
        throw e;
    } finally {
        pw.close();
    }
    return image;
}
Also used : PngWriter(ar.com.hjg.pngj.PngWriter) PngMetadata(ar.com.hjg.pngj.chunks.PngMetadata) Entry(java.util.Map.Entry) ChunksListForWrite(ar.com.hjg.pngj.chunks.ChunksListForWrite) ColorModel(java.awt.image.ColorModel) IndexColorModel(java.awt.image.IndexColorModel) PngChunkTRNS(ar.com.hjg.pngj.chunks.PngChunkTRNS) RenderedImage(java.awt.image.RenderedImage) ImageInfo(ar.com.hjg.pngj.ImageInfo) PngChunkPLTE(ar.com.hjg.pngj.chunks.PngChunkPLTE) IndexColorModel(java.awt.image.IndexColorModel)

Aggregations

ImageInfo (ar.com.hjg.pngj.ImageInfo)5 PngWriter (ar.com.hjg.pngj.PngWriter)5 ImageLineInt (ar.com.hjg.pngj.ImageLineInt)4 PngChunkPLTE (ar.com.hjg.pngj.chunks.PngChunkPLTE)3 PngChunkTRNS (ar.com.hjg.pngj.chunks.PngChunkTRNS)3 ByteArrayOutputStream (java.io.ByteArrayOutputStream)3 ChunksListForWrite (ar.com.hjg.pngj.chunks.ChunksListForWrite)1 PngChunkTEXT (ar.com.hjg.pngj.chunks.PngChunkTEXT)1 PngMetadata (ar.com.hjg.pngj.chunks.PngMetadata)1 ColorModel (java.awt.image.ColorModel)1 IndexColorModel (java.awt.image.IndexColorModel)1 RenderedImage (java.awt.image.RenderedImage)1 Date (java.util.Date)1 Entry (java.util.Map.Entry)1 CacheControl (javax.ws.rs.core.CacheControl)1 WTWD (org.opentripplanner.analyst.request.SampleGridRenderer.WTWD)1 SampleGridRequest (org.opentripplanner.analyst.request.SampleGridRequest)1 ZSamplePoint (org.opentripplanner.common.geometry.ZSampleGrid.ZSamplePoint)1 GenericLocation (org.opentripplanner.common.model.GenericLocation)1 RoutingRequest (org.opentripplanner.routing.core.RoutingRequest)1