Мое требование состоит в том, что мне нужно преобразовать цветное изображение в изображение с серой шкалой и получить пиксельные значения изображения с серой шкалой в массив и выполнить некоторый алгоритм шифрования на этом массиве и снова использовать этот измененный массив пикселей, мне нужно преобразовать обратно/создать изображение с серой шкалой и отображение его. Вот мои сомнения.
Используя цветное изображение, я получил значения пикселей RGB в трех разных массивах. По моим сведениям, пиксели серой шкалы можно получить, выполнив red+green+blue/3=gray
. Здесь красный, синий, зеленый, серый - это 2-D массивы. Правильно ли это, чтобы получить значения пикселя серого?
gray[x][y] = (r[x][y]+g[x][y]+b[x][y])/3;
Если это правильно, то я могу легко выполнить алгоритм на этом массиве. Здесь возникает реальная проблема. Как преобразовать назад/создать изображение с серой шкалой с использованием этой матрицы пикселей. Примером может служить пример, показывающий, как изображение в сером масштабе может быть создано с использованием значений пикселей. Спасибо.
for(int x = 0;x<=height;x++) {
for(int y = 0;y<=width;y++) {
gray[x][y] = (r[x][y]+g[x][y]+b[x][y])/3;
System.out.print(gray[x][y]+"\t");
}
System.out.println(" ");
}
Вместо преобразования изображения в оттенки серого, манипулируя пикселями, я бы предложил создать новый BufferedImage из TYPE_BYTE_GRAY. Затем вы можете напрямую манипулировать пикселями.
public static BufferedImage convertToGray(BufferedImage biColor)
{
BufferedImage biGray = new BufferedImage(biColor.getWidth(), biColor.getHeight(), BufferedImage.TYPE_BYTE_GRAY);
biGray.getGraphics().drawImage(biColor, 0, 0, null);
return biGray;
}
public static void manipulatePixels(BufferedImage biGray)
{
byte [] imageData = ((DataBufferByte)biGray.getRaster().getDataBuffer()).getData();
for (int i = 0; i < imageData.length; i++)
{
// do manipulation/encryption here - or on the entire array at once
}
}
Если по какой-то причине вы хотите создать совершенно новый образ из массива байтов, просто создайте новое изображение и скопируйте пиксели в его массив байтов.
public static BufferedImage createImageFromArray(byte[] imageData, int width, int height)
{
BufferedImage newImage = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);
byte [] newData = ((DataBufferByte) newImage.getRaster().getDataBuffer()).getData();
for (int i = 0; i < imageData.length; i++)
{
newData[i] = imageData[i];
}
return newImage;
}
public class GrayScaleTest {
public void convert(int[] r, int[] g, int[] b, int imageWidth, int imageHeight) {
int[] grayScaleValues = converToGrayscale(r,g,b);
int[] encryptedValues = encryptValues(grayScaleValues);
BufferedImage imageFromGrayScale = createImage(grayScaleValues, imageWidth, imageHeight);
BufferedImage imageFromEncryptedValues = createImage(encryptedValues, imageWidth, imageHeight);
}
private BufferedImage createImage(int[] values, int imageWidth, int imageHeight) {
BufferedImage image = new BufferedImage(128, 128, BufferedImage.TYPE_INT_ARGB);
int[] raster = ((DataBufferInt) image.getRaster().getDataBuffer()).getData();
System.arraycopy(values,0,raster,0,raster.length);
return image;
}
private int[] encryptValues(int[] grayScaleValues) {
// run your encryption
// I just return input
return grayScaleValues;
}
private int[] converToGrayscale(int[] r, int[] g, int[] b) {
int sz = r.length;
int[] grayscale = new int[sz];
for(int i = 0; i < sz; i++) {
grayscale[i] = (r[i] + g[i] + b[i]) / 3;
}
return grayscale;
}
}
Конечно, вы можете использовать другой тип bufferedimage, но я не хотел иметь дело с чем-то другим, кроме ints для этого. Но этот фрагмент кода должен делать то, что я думаю, что вы хотите сделать.
существует несколько способов преобразования цвета в оттенки серого, ваш путь является самым простым и правильным.
вы можете превратить свой массив обратно в изображение, используя этот http://www.java2s.com/Tutorial/Java/0261__2D-Graphics/CreateBufferredImagewithcolorsbasedonintegerarray.htm
BufferedImage image = new BufferedImage(width, height,BufferedImage.TYPE_INT_RGB);
image.setRGB(0, 0, width, height, data, 0, width);
в то время как данные являются 1D IntegerArray с длиной (надеюсь, что я не смешивал индексы)
int[] data=new int[height*width];
for (int i=0;i<height;i++){
for (int k=0;k<width;k++){
//EDIT: The gray[][] array, is the one you already got.
data[i*width+k]=getIntFromColor(gray[i][k],gray[i][k],gray[i][k]);
}
}
где метод создания правильного целого из вашего colorcode (int, int, int) приведен в: как преобразовать цвет rgb в int в java
public int getIntFromColor(int Red, int Green, int Blue){
Red = (Red << 16) & 0x00FF0000; //Shift red 16-bits and mask out other stuff
Green = (Green << 8) & 0x0000FF00; //Shift Green 8-bits and mask out other stuff
Blue = Blue & 0x000000FF; //Mask out anything not blue.
return 0xFF000000 | Red | Green | Blue; //0xFF000000 for 100% Alpha. Bitwise OR everything together.
}
Приветствие Рейнеке