Как создать серое изображение из значений пикселей с помощью Java

1

Мое требование состоит в том, что мне нужно преобразовать цветное изображение в изображение с серой шкалой и получить пиксельные значения изображения с серой шкалой в массив и выполнить некоторый алгоритм шифрования на этом массиве и снова использовать этот измененный массив пикселей, мне нужно преобразовать обратно/создать изображение с серой шкалой и отображение его. Вот мои сомнения.

  1. Используя цветное изображение, я получил значения пикселей RGB в трех разных массивах. По моим сведениям, пиксели серой шкалы можно получить, выполнив red+green+blue/3=gray. Здесь красный, синий, зеленый, серый - это 2-D массивы. Правильно ли это, чтобы получить значения пикселя серого?

    gray[x][y] = (r[x][y]+g[x][y]+b[x][y])/3;
    
  2. Если это правильно, то я могу легко выполнить алгоритм на этом массиве. Здесь возникает реальная проблема. Как преобразовать назад/создать изображение с серой шкалой с использованием этой матрицы пикселей. Примером может служить пример, показывающий, как изображение в сером масштабе может быть создано с использованием значений пикселей. Спасибо.

    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(" ");
    }
    
  • 0
    Смотрите java.awt.Image.ColorModel
  • 0
    Цветовая модель используется, чтобы получить значения пикселей RGB, верно? Мое требование состоит в том, чтобы создать серое изображение, используя массив пикселей
Показать ещё 6 комментариев
Теги:
image
grayscale
bufferedimage

3 ответа

1

Вместо преобразования изображения в оттенки серого, манипулируя пикселями, я бы предложил создать новый 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;
}
  • 0
    Данный пример предназначен для получения значений пикселей изображения в градациях серого. Можете ли вы сказать мне, как я могу создать изображение в градациях серого, используя значения пикселей (т. Е. Байтовый массив imageData для изображения в градациях серого).
  • 0
    Обновил мой ответ.
Показать ещё 4 комментария
0
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 для этого. Но этот фрагмент кода должен делать то, что я думаю, что вы хотите сделать.

  • 0
    BufferedImage.TYPE_INT_ARGB для изображения в оттенках серого или изображения RGB?
  • 0
    Растровая переменная может принимать только одномерный массив, но мои массивы (r [] [], g [] [], b [] [], grey [] []) являются двумерными массивами. я должен скопировать (серый [] [] ---> 2-D массив в 1-D массив и затем выполнить задачу?
Показать ещё 1 комментарий
0

существует несколько способов преобразования цвета в оттенки серого, ваш путь является самым простым и правильным.

вы можете превратить свой массив обратно в изображение, используя этот 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.
}

Приветствие Рейнеке

  • 0
    Хай, ссылка, которую вы дали, чтобы превратить ваш массив в изображение, предназначена для цветного изображения (RGB-массивы есть). Я хочу получить серое изображение из одного массива
  • 0
    единственное отличие состоит в том, что в оттенках серого красная / синяя / зеленая части одинаковы. и я написал, что ваш алгоритм получения оттенков серого правильный ??

Ещё вопросы

Сообщество Overcoder
Наверх
Меню