3

I need to create a grayscale image from data in an nio ShortBuffer. I have a function that maps the data in the ShortBuffer to unsigned byte but is in an int (easily changed). The method I found uses an RGB plus transparency color model and appears to be quite inefficent. i have not been able to see how to apply the TYPE_BYTE_GRAY and modify the code. i'm new to Java. Here's my code:

    public void paintComponent(Graphics g) {
    final BufferedImage image;
    int[] iArray = {0, 0, 0, 255};  //  pixel

    image = (BufferedImage) createImage(WIDTH, HEIGHT);

    WritableRaster raster = image.getRaster();
    sBuf.rewind();  // nio ShortBuffer
    for (int row = 0; row < HEIGHT; row++) {
        for (int col = 0; col < WIDTH; col++) {
            int v = stats.mapPix(sBuf.get());  // map short to byte
            iArray[0] = v;  // RGBT
            iArray[1] = v;  
            iArray[2] = v;
            raster.setPixel(col, row, iArray);
        }
    }
    g.drawImage(image, 0, 0, getWidth(), getHeight(), null);
}

TIA Nate

Nate Lockwood
  • 3,325
  • 6
  • 28
  • 34

2 Answers2

5

Insted of using a ColorConvertOp, you could simply create a new gray scale BufferedImage and paint the original colored image onto it:

public static BufferedImage convertToGrayScale(BufferedImage image) {
  BufferedImage result = new BufferedImage(
            image.getWidth(),
            image.getHeight(),
            BufferedImage.TYPE_BYTE_GRAY);
  Graphics g = result.getGraphics();
  g.drawImage(image, 0, 0, null);
  g.dispose();
  return result;
}

This should perform significantly faster and give better results than using the filter() method.

A great tuturial (including instruction on how to use a GrayFilter) can be found here: http://www.tutorialized.com/tutorial/Convert-a-Color-Image-to-a-Gray-Scale-Image-in-Java/33347

Clayton Louden
  • 1,056
  • 2
  • 11
  • 28
4

One approach would be to create the BufferedImage by writing to the raster as you are doing now. Once you have the BufferedImage, you can convert it to TYPE_BYTE_GRAY using the filter() method of ColorConvertOp, as shown in this example.

trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • Thanks, I did find out how to create a gray bufferedimage and got it working and put most of the code in paint in a method. My program now is much like yours except that I don't read in a JPEG file. I see that paint is called twice, is that normal? – Nate Lockwood Jun 25 '10 at 17:40
  • @shellback3: The example reads a JPEG, but your code constructs a `BufferedImage` directly from raw data. I don't see any `paint()` method; you can edit your question to show additional code. – trashgod Jun 25 '10 at 18:48
  • Thanks, I figured out how to do that - the paint() was elsewhere. (Now to learn how to print a short as an unsigned short - it never ends). I will get my data directly from a device (or saved in a file) as a sequence of bytes, probably in a bytebuffer. – Nate Lockwood Jun 30 '10 at 21:43
  • A related example using icons is shown [here](http://stackoverflow.com/a/12228640/230513). – trashgod Sep 06 '15 at 02:01