WritableRaster 方法 setPixels() 需要什么类型的数组?

Sam*_*hah 1 java shared-secret javax.imageio

我不明白 Java 的 WritableRaster 类是如何工作的。我尝试查看文档,但不明白它如何从像素数组中获取值。另外,我不确定像素阵列由什么组成。

这里我解释一下。

我想要做的是:Shamir 在图像上的秘密分享。为此,我需要在 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);
Run Code Online (Sandbox Code Playgroud)

// 现在采用那些 rgb 值。我使用一些函数更改它们并返回一个 int 值。像这样的东西:

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

// 这个二维数组像素具有所有新的颜色值,对吗?但是现在我想使用这个新值构建一个图像。所以我所做的是。首先将此像素数组转换为列表。现在这个列表有新图像的像素值。但是要使用 RasterObj.setPixels() 方法构建图像,我需要一个带有 RGB 值的数组 [我可能在这里出错了!] 所以我获取列表的各个值并找到 rgb 值并将其连续放入一个新的一维数组 pixelvector ..这样的(r1,g1,b1,r2,g2,b2,r3,g3,b3...)

列表的大小是 w h,因为它包含每个像素的单个像素值。但是,新数组像素向量的大小将变为 w h*3,因为它包含每个像素的 r、g、b 值。

然后为了形成图像,我这样做:Snippet

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"));
Run Code Online (Sandbox Code Playgroud)

如果我在 setPixels() 方法中放置一个只有单个像素值的数组,它不会从该函数返回!但是如果我放置一个具有单独 r,g,b 值的数组,它会从函数返回。但是对 share1 、 share 2 等做同样的事情。我只得到蓝色阴影。所以,我什至不确定我是否能够重建图像。

PS - 这可能看起来像我知道的一个非常愚蠢的代码。但我只有一天时间来做这件事并学习 Java 中的图像。所以我正在尽我所能。

谢谢..

har*_*ldK 5

A Raster(likeWriteableRaster及其子类)由 aSampleModel和 a 组成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"));
Run Code Online (Sandbox Code Playgroud)

我假设用于修改每个像素值的其余代码是正确的。:-)

但只是一个提示:如果您使用一维数组而不是二维数组,您会更容易(并且由于转换较少而更快)。IE:

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];
     }
 }
Run Code Online (Sandbox Code Playgroud)