How to initialize the ShortProcessor?

imagej1
java

#1

Hello,

I tried to create 16-bit GRAYSCALE image.
But I get error when use this constructor :: new ShortProcessor(w,h,short[],ColorModel);
Is this my mistake?

My procedures are following,

Method 1(get error);

ColorModel cm = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_GRAY),false,false,ColorModel.OPAQUE,DataBuffer.TYPE_USHORT);
ShortProcessor sp2 = new ShortProcessor(512, 512,pixelsShort,cm);
ImagePlus imp2 = new ImagePlus("", sp2);
imp2.show();
Exception in thread "main" java.lang.IllegalArgumentException: Raster ByteInterleavedRaster: width = 512 height = 512 #numDataElements 1 dataOff[0] = 0 is incompatible with ColorModel ColorModel: #pixelBits = 16 numComponents = 1 color space = java.awt.color.ICC_ColorSpace@311d617d transparency = 1 has alpha = false isAlphaPre = false
	at java.awt.image.BufferedImage.<init>(BufferedImage.java:622)
	at ij.process.ShortProcessor.createBufferedImage(ShortProcessor.java:156)
	at ij.process.ShortProcessor.createImage(ShortProcessor.java:117)
	at ij.ImagePlus.getImage(ImagePlus.java:484)
	at ij.ImagePlus.show(ImagePlus.java:421)
	at ij.ImagePlus.show(ImagePlus.java:402)

Method 2(it seems show images correctly, …why…);

ShortProcessor sp2 = new ShortProcessor(512, 512);
sp2.setPixels(pixelsShort);
ImagePlus imp2 = new ImagePlus("", sp2);
imp2.show();

Thanks,
Tatsuaki


#2

Hello Tatsuaki -

The problem is that you are building an ImagePlus that uses a
16-bit grayscale ColorModel. As I understand it, even though
ImageJ works with various image types – shorts, floats –
under the hood ImageJ displays (non-color) images using 8 bits.

So when you try to display your ImagePlus you have a
mismatch between the ByteInterleavedRaster (note the
Byte) and the 16-bit entries in your ColorModel (LUT).

Your “Method 2” works fine, but if you prefer to pass your pixel
array for your ShortProcessor in through the constructor,
your can pass null for the ColorModel constructor argument,
and ImageJ will provide you with its default grayscale ColorModel.

If you need to pass in your own ColorModel (Reading between
the lines, I assume that you don’t really want to, but you needed
to provide a ColorModel argument to ShortProcessor's
constructor.), you can pass in an 8-bit ColorModel, that is of
“transfer type” DataBuffer.TYPE_BYTE (rather than
DataBuffer.TYPE_USHORT).

This is all illustrated by the following java plugin:

import java.awt.color.ColorSpace;
import java.awt.image.*;

import ij.*;
import ij.plugin.PlugIn;
import ij.process.ShortProcessor;

public class My_Plugin implements PlugIn {
  public void run(String arg) {
    short[] pixelsShort = new short[512 * 512];
    for (short y = 0; y < 512; y++)
      for (short x = 0; x < 512; x++)
	pixelsShort[y * 512 + x] = x;

    ShortProcessor sp2 = new ShortProcessor (512, 512, pixelsShort, null);
    ImagePlus imp2 = new ImagePlus ("null CM", sp2);
    imp2.show();

    ColorModel cma = new ComponentColorModel (ColorSpace.getInstance (ColorSpace.CS_GRAY), false, false, ColorModel.OPAQUE, DataBuffer.TYPE_BYTE);
    ShortProcessor sp2a = new ShortProcessor (512, 512, pixelsShort, cma);
    ImagePlus imp2a = new ImagePlus ("TYPE_BYTE CM", sp2a);
    imp2a.show();

    ColorModel cmb = new ComponentColorModel (ColorSpace.getInstance (ColorSpace.CS_GRAY), false, false, ColorModel.OPAQUE, DataBuffer.TYPE_USHORT);
    ShortProcessor sp2b = new ShortProcessor (512, 512, pixelsShort, cmb);
    ImagePlus imp2b = new ImagePlus ("TYPE_USHORT CM", sp2b);
    imp2b.show();  // throws when ImageJ attempts to display this image
  }
}

Note, as you’ve seen, you can create the ImagePlus with the
16-bit ColorModel; you just can’t display it. The above plugin
throws only when it calls imp2b.show().

Thanks, mm


#3

Hello, mm

Thank you for your explanation. I have understand.

I’m sorry, I totally thought should set same as DataBufferType of pixels and DataBufferType of ColorModel.
From now on, I have set the DataBufferTypeByte or null when I use IJ.jar.

Thanks.


#4

Hello Tatsuaki -

I see why one might try to match the data types and therefore
use (in this case) a TYPE_USHORT “transfer type” for the
ColorModel.

But the right way to understand this is that the ColorModel
converts (through a lookup table) pixel values from the type
they are stored as to a type used for display, and these types
are often different.

A very common example of this is a palletized (“false color”)
8-bit image. Pixels are stored as bytes (often to save space),
and the ColorModel translates them to 24-bit rgb values (or
32-bit alpha-rgb values) for display.

Thanks, mm


#5

Hello, mm

I keep in mind about “a palletized (“false color”) 8-bit image”.

Thanks.