-2

I am writing an ImageEncoder that writes a TGA image. I have been able to successfully write the TGA file, but instead of ending up with [RRRRRGGGGGBBBBBA] I get [RGBBBBBA] here is the relevant code:

int lastRow = minY + height;
for (int row = minY; row < lastRow; row += 8) {
    int rows = Math.min(8, lastRow - row);
    int size = rows * width * numBands;

    // Grab the pixels
    Raster src = im.getData(new Rectangle(minX, row, width, rows));
    src.getPixels(minX, row, width, rows, pixels);

    for (int i = 0; i < size; i++) {
        //output.write(pixels[i] & 0xFF);
        //corrected
        //before conversion (source image) pixel in RGBA8888 format.
        int o = (int) pixels[i];
        //Need to convert here...
        short converted = ?;
        //need to write out RGB5551
        output.write(converted);
    }
}

To clarify what I am trying to accomplish... I have a source image in png format the color depth is RGBA8888. I need to convert this image to tga format with color depth RGBA5551. The for loop above is where I am accessing the individual pixels. So what I am asking is: How do I correctly read the 32-bit int (RGBA8888) and convert it to a 16-bit short (RGBA5551)?

Vadim K.
  • 2,370
  • 18
  • 26
Jason Palmer
  • 99
  • 2
  • 8
  • 1
    Hi. Asking people to spot errors in your code is not especially productive. You should use the debugger (or add print statements) to isolate the problem, by tracing the progress of your program, and comparing it to what you expect to happen. As soon as the two diverge, then you've found your problem. (And then if necessary, you should construct a [minimal test-case](http://sscce.org).) – Oliver Charlesworth Sep 29 '13 at 08:55
  • Try to explain with sentences what your program really do. I don't understand with the pixels (int[]) (32 bits) are casted into short (16 bits) – Aubin Sep 29 '13 at 09:00

2 Answers2

1

Unfortunately nobody was able to help me with this one, but I would like to share the answer with the community.

 private void writeoutFromPNGFile(int width, int numBands, int minY, int height,         RenderedImage im, int minX) throws IOException {
    System.out.println("Writing from PNG data.");
    //convertTo2DWithoutUsingGetRGB(im);
    //now start writing the file...
    int[] pixels = new int[8 * width * numBands];

    int count = 0;

    // Process 8 rows at a time so all but the last will have
    // a multiple of 8 pixels.  This simplifies PBM_RAW encoding.
    int lastRow = minY + height;
    for (int row = minY; row < lastRow; row += 8) {
        int rows = Math.min(8, lastRow - row);
        int size = rows * width * numBands;

        // Grab the pixels
        Raster src = im.getData(new Rectangle(minX, row, width, rows));
        src.getPixels(minX, row, width, rows, pixels);

        for (int i = 0; i < size; i += 4) {
            //output.write(pixels[i] & 0xFF);
            int red = pixels[i];
            int green = pixels[i + 1];
            int blue = pixels[i + 2];
            int alpha = pixels[i + 3];
            //System.out.println("Pixel Value: " + o);
            convertTo5551(red, green, blue, alpha);
        }

    }
}


int convertTo5551(int r, int g, int b, int a) throws IOException {
    int r5 = r * 31 / 255;
    int g5 = (int) g * 31 / 255;
    int b5 = (int) b * 31 / 255;
    int a1 = (a > 0) ? 0 : -1;
    int rShift = (int) r5 << 11;
    int bShift = (int) g5 << 6;
    int gShift = (int) b5 << 1;
    // Combine and return
    int abgr5551 = (int) (bShift | gShift | rShift | a1);
    output.write(new BigDecimal((abgr5551) & 0xFF).byteValue());
    output.write(new BigDecimal((abgr5551 >> 8) & 0xFF).byteValue());
    return abgr5551;
}

The colors are converted using linear math - not a good idea for good results. Color Reduction should really be done with a program like ImageMagick.

Jason Palmer
  • 99
  • 2
  • 8
0

Since Raster knows about its own source (rectangle) I would expect to read src.getPixels( 0, 0, width,rows,pixels). Didn't try it though.

halfbit
  • 3,414
  • 1
  • 20
  • 26