Какой тип массива требуется в методе WritableRaster setPixels()?

Я не понимаю, как работает класс WritableRaster Java. Я пытался посмотреть документацию, но не понимаю, как она берет значения из массива пикселей. Кроме того, я не уверен, из чего состоит массив пикселей.

Вот поясняю.

То, что я хочу сделать, это: Секретный обмен изображениями Шамира. Для этого мне нужно получить изображение из изображения BuferedImage. Я беру секретный образ. Создайте общие ресурсы, запустив «функцию» для каждого пикселя изображения. (в основном изменяя значения пикселей чем-то)

Фрагмент:

int w = image.getWidth();
int h = image.getHeight();
for (int i = 0; i < h; i++) 
    {
    for (int j = 0; j < w; j++) 
        {
        int pixel = image.getRGB(j, i);

        int red = (pixel >> 16) & 0xFF;
        int green = (pixel >> 8) & 0xFF;
        int blue = (pixel) & 0xFF;

        pixels[j][i] = share1(red, green, blue);

// Теперь берем эти значения RGB. Я меняю их с помощью некоторой функции и возвращаю значение int. Что-то вроде этого:

public int share1 (r, g, b)
{
a1 = rand.nextInt(primeNumber);
total1 = r+g+b+a1;
new_pixel = total1 % primeNumber;
return new_pixel;
}

// Этот 2d массив пикселей имеет все новые значения цвета, верно? Но теперь я хочу создать изображение, используя эти новые значения. Итак, что я сделал. Сначала преобразовал этот массив пикселей в список. Теперь в этом списке есть значения пикселей нового изображения. Но для создания изображения с использованием метода RasterObj.setPixels() мне нужен массив со значениями RGB [ЗДЕСЬ Я МОГУ ОШИБАТЬСЯ!]. Поэтому я беру отдельные значения списка, нахожу значения rgb и последовательно помещаю их в новый пиксельный вектор массива 1D. ..что-то вроде этого (r1,g1,b1,r2,g2,b2,r3,g3,b3...)

Размер списка wh, так как он содержит значение одного пикселя для каждого пикселя. НО, Размер нового пиксельного вектора массива станет wh*3, так как он содержит значения r,g,b каждого пикселя..

Затем, чтобы сформировать изображение, я делаю это: Фрагмент

BufferedImage image_share1 = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
WritableRaster rast = (WritableRaster) image_share1.getData();
rast.setPixels(0, 0, w, h, pixelvector);
image_share1.setData(rast);
ImageIO.write(image_share1,"JPG",new File("share1.jpg"));

Если я помещу массив со значениями только одного пикселя в метод setPixels(), он не вернется из этой функции! Но если я помещу массив с отдельными значениями r, g, b, он вернется из функции. Но делая то же самое для share1 , share 2 и т. д. Я не получаю ничего, кроме оттенков синего. Так что я даже не уверен, что смогу восстановить изображение..

PS - Это может выглядеть как очень глупый код, который я знаю. Но у меня был всего один день, чтобы сделать это и узнать об изображениях в Java. Поэтому я делаю все, что могу.

Спасибо..


person Samarth Shah    schedule 09.12.2014    source источник
comment
rast.setPixels(0, 0, w, h, вектор пикселей); На основе документа эта функция устанавливает для всего изображения цвет «пиксельного вектора». Здесь - docs.oracle.com/javase/ 7/docs/api/java/awt/изображение/   -  person new Objekt    schedule 10.12.2014
comment
возможный дубликат Превратить массив пикселей в объект изображения с помощью Java ImageIO?   -  person Dioxin    schedule 10.12.2014
comment
@newObjekt.. Да, я знаю, но, как я уже сказал, я не понимаю документацию. Он устанавливает все изображение, принимая 3 значения из этого массива за раз, LIKE: r,g,b или принимает только 1 значение?   -  person Samarth Shah    schedule 10.12.2014
comment
@VinceEmigh Да, но чего я не понимаю, так это массив pixelvector. Должен ли он содержать 1 значение/пиксель или 3 последовательных значения/пиксель??   -  person Samarth Shah    schedule 10.12.2014
comment
Переименуйте свой вопрос, чтобы быть более конкретным. Что вы имеете в виду 3 последовательных пикселя? Массив должен содержать все пиксели изображения. Вы понимаете, как работают пиксели в одномерном массиве? Вы вычисляете, какой пиксель устанавливается с помощью x + (y * width) (вам не нужно использовать формулу, я просто показываю вам, как вы выбираете, к какому пикселю обращаться)   -  person Dioxin    schedule 10.12.2014
comment
@VinceEmigh только одна последняя вещь: если я хочу сделать изображение шириной w и высотой h ... мне нужно ввести массив размера (wh) в методе setPixels (), т. Е. Массив значений пикселей . ИЛИ мне нужно ввести массив размера (wh*3) в метод setPixels(). КАК этот метод будет принимать значения из массива pixelvector?   -  person Samarth Shah    schedule 10.12.2014


Ответы (1)


Raster (как и WriteableRaster и его подклассы) состоит из SampleModel и DataBuffer. SampleModel описывает макет сэмпла (это пиксели упакованы, пиксели чередуются, полосы чередуются? сколько полос? и т. д.) и размеры, а DataBuffer описывает фактическое хранилище (байты сэмплов, короткие, целые, со знаком или без знака). • одиночный массив или массив на полосу?и т.д...).

Для BufferedImage.TYPE_INT_RGB сэмплы будут упакованы в пиксели (все 3 сэмпла R, G и B упакованы в один int для каждого пикселя) и тип данных/передачи DataBuffer.TYPE_INT.

Извините, что не ответил на ваш вопрос относительно WritableRaster.setPixels(...) напрямую, но я не думаю, что это тот метод, который вы ищете (в большинстве случаев это не так). :-)

Для вашей цели, я думаю, вы должны сделать что-то вроде:

// Pixels in TYPE_INT_RGB format 
// (ie. 0xFFrrggbb, where rr is two bytes red, gg two bytes green etc)
int[] pixelvector = new int[w * h]; 

BufferedImage image_share1 = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
WritableRaster rast = image_share1.getRaster(); // Faster! No copy, and live updated
rast.setDataElements(0, 0, w, h, pixelvector);
// No need to call setData, as we modified image_share1 via it's raster

ImageIO.write(image_share1,"JPG",new File("share1.jpg"));

Я предполагаю, что остальная часть вашего кода для изменения каждого значения пикселя верна. :-)

Но небольшой совет: вам будет проще (и быстрее из-за меньшего преобразования), если вы будете использовать одномерный массив вместо двумерного. То есть:

int[] pixels = new int[w * h]; // instead of int[][] pixels = new int[w][h];

// ...

for (int y = 0; y < h; y++) {
    for (int x = 0; x < w; x++) {

        // ...

        pixels[y * w + x] = share1(red, green, blue); // instead of pixels[x][y];
     }
 }
person Harald K    schedule 10.12.2014
comment
Это работает и сделало мой код действительно коротким и быстрым. Большое спасибо. Еще одна вещь, можете ли вы сказать мне, правильный ли мой метод share1? Что я хочу сделать, так это получить значения Red, Green, Blue исходного пикселя, а затем вызвать share1..в этом я добавляю и несколько случайных вещей и возвращаю значение new_pixel..НО, старые значения пикселей равны -60000 или около того, а новые значения пикселей равны 150 или 200. Это правильно? Мне нужно вернуть упакованное значение пикселя RGB. Я должен вернуть шумоподобные изображения!! кем я не являюсь!! - person Samarth Shah; 10.12.2014
comment
Хорошо! :-) Я не знаю алгоритма, который вы здесь пытаетесь реализовать, поэтому сложно сказать наверняка. Но мне выглядит немного странно просто суммировать r, g и b. Может быть, вам следует вычислить каждое значение отдельно, а затем заново создать упакованный формат RGB, используя int newPixel = 0xff000000 | (r & 0xff) << 16 | (g & 0xff) << 8 | (b & 0xff);? - person Harald K; 10.12.2014
comment
Что ж, я пытаюсь зашифровать изображение (Shamir's Secret Sharing)/ Для этого мне нужно запустить функцию, которая сопоставляет значения R, G, B только с одним значением, которое является цветом пикселя зашифрованного изображения. (Они должны быть похожи на серый шум). Функция = (R + G + B + a) по простому модулю. [a — случайное число]. СЕЙЧАС эта функция хочет, чтобы я суммировал значения RGB... странно... поэтому я не могу использовать ваш подход... - person Samarth Shah; 10.12.2014
comment
Понятно... Ну, я просмотрел статью в Википедии, но она слишком техническая для меня, чтобы понять за 30 секунд... ;-) Поэтому я предлагаю вам задать еще один вопрос конкретно по этому поводу. Но я не понимаю, как этот метод может создать что-либо, кроме зеленовато-голубого изображения (или синего, если prime меньше 255). Может быть (val = результат функции) int newPixel = 0xff000000 | (val & 0xff) << 16 | (val & 0xff) << 8 | (val & 0xff); тогда? Это должно по крайней мере создать серый шум. Или вам нужно убедиться, что основное число находится между 255 * 255 и 255 * 255 * 255. Это может сработать. - person Harald K; 10.12.2014