Есть два хороших способа сделать это, в зависимости от вашего варианта использования.
Создайте новое серое изображение и скопируйте в него данные. Это будет держать изображение «управляемым», что может привести к лучшей производительности рендеринга (т.е. на экране). Но для этого потребуется вдвое больше памяти, и скопируйте данные из вашего ввода в изображение.
Другой способ - создать серое изображение непосредственно «вокруг» существующих данных пикселей. Это будет быстрее и практически не использует лишнюю кучу, поскольку позволяет избежать копирования данных пикселей. Но изображение не будет управляемым (так как резервный массив открыт и изменчив).
Оба варианта показаны ниже:
int w = 640;
int h = 480;
byte[] imageBytes = new byte[w * h];
// 1 Keeps the image "managed" at the expense of twice the memory + a large array copy
BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_BYTE_GRAY);
image.getRaster().setDataElements(0, 0, w, h, imageBytes);
System.out.println("image: " + image);
// 2 Faster, and uses less memory, but will make the image "unmanaged"
ColorModel cm = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_GRAY), false, false, Transparency.OPAQUE, DataBuffer.TYPE_BYTE);
WritableRaster raster = Raster.createInterleavedRaster(new DataBufferByte(imageBytes, imageBytes.length), w, h, w, 1, new int[]{0}, null);
BufferedImage image2 = new BufferedImage(cm, raster, cm.isAlphaPremultiplied(), null);
System.out.println("image2: " + image2);
Если данные изображения не находятся в линейном пространстве серого цвета, можно использовать IndexColorModel
, чтобы отобразить ввод в любой диапазон, который вы хотите:
// Alternate, using IndexColorModel, if your input isn't in linear gray color space
int[] cmap = new int[256]; // TODO: Add ARGB packed colors here...
IndexColorModel icm = new IndexColorModel(8, 256, cmap, 0, false, -1, DataBuffer.TYPE_BYTE);
// As 1
BufferedImage image3 = new BufferedImage(w, h, BufferedImage.TYPE_BYTE_INDEXED, icm);
image3.getRaster().setDataElements(0, 0, w, h, imageBytes);
System.out.println("image3: " + image3);
// As 2
BufferedImage image4 = new BufferedImage(icm, raster, cm.isAlphaPremultiplied(), null);
System.out.println("image4: " + image4);