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

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

Здесь я объясняю.

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

Snippet:

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;
}

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

Размер списка составляет w h, потому что он содержит одно пиксельное значение каждого пикселя. НО, размер нового массива pixelvector станет w h * 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. Так что я делаю все, что могу.

Спасибо..

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];
     }
 }
Другие вопросы по тегам