Search in sources :

Example 1 with ImageLineInt

use of ar.com.hjg.pngj.ImageLineInt 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 ImageLineInt

use of ar.com.hjg.pngj.ImageLineInt 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 ImageLineInt

use of ar.com.hjg.pngj.ImageLineInt 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 ImageLineInt

use of ar.com.hjg.pngj.ImageLineInt 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)

Aggregations

ImageInfo (ar.com.hjg.pngj.ImageInfo)4 ImageLineInt (ar.com.hjg.pngj.ImageLineInt)4 PngWriter (ar.com.hjg.pngj.PngWriter)4 ByteArrayOutputStream (java.io.ByteArrayOutputStream)3 PngChunkPLTE (ar.com.hjg.pngj.chunks.PngChunkPLTE)2 PngChunkTRNS (ar.com.hjg.pngj.chunks.PngChunkTRNS)2 PngChunkTEXT (ar.com.hjg.pngj.chunks.PngChunkTEXT)1 Date (java.util.Date)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 Router (org.opentripplanner.standalone.Router)1