【问题标题】:What type of array required in WritableRaster method setPixels()?WritableRaster 方法 setPixels() 中需要什么类型的数组?
【发布时间】:2015-02-07 22:52:58
【问题描述】:

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

我在这里解释一下。

我想做的是:Shamir 在图像上的秘密分享。为此,我需要在 BufferedImage 图像中获取图像。我拍了一张秘密照片。通过在图像的每个像素上运行“函数”来创建共享。 (基本上是通过一些东西改变像素值)

片段:

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 值并将其连续放入新的一维数组中 像素向量..类似这样的东西 (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 中的图像。所以我正在尽我所能。

谢谢..

【问题讨论】:

  • rast.setPixels(0, 0, w, h, pixelvector);根据文档,该函数将整个图像设置为“pixelvector”的颜色。这里 - docs.oracle.com/javase/7/docs/api/java/awt/image/…
  • @newObjekt..是的,我知道,但正如我所说,我不理解文档。它是通过一次从该数组中获取 3 个值来设置整个图像,例如:r、g、b 还是只需要 1 个值。?
  • @VinceEmigh 是的,但我不明白的是数组像素向量。它应该包含 1 个值/像素还是 3 个连续值/像素。??
  • 重命名您的问题以更具体。 3 个连续像素 是什么意思?该数组应包含图像中的所有像素。你了解一维数组中的像素是如何工作的吗?您使用x + (y * width) 计算正在设置的像素(您不需要使用公式,我只是向您展示如何选择要访问的像素)

标签: java javax.imageio shared-secret


【解决方案1】:

Raster(如WriteableRaster 及其子类)由SampleModelDataBuffer 组成。 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"));

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

但只是一个提示:如果您使用 1D 数组而不是 2D 数组,您自己会更轻松(并且由于更少的转换而更快)。即:

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

【讨论】:

  • 它可以工作,让我的代码变得更短更快速。非常感谢。还有一件事,你能告诉我我的 share1 方法是否正确吗?我想要做的是获取原始像素的红色、绿色、蓝色值,然后调用 share1 ..在那,我添加多个随机的东西并返回一个 new_pixel 值..但是,旧的像素值就像 -60000左右,新的像素值就像 150 或 200 ..它正确吗?我需要返回一个打包的 RGB 像素值。我应该返回类似噪声的图像!我不是!
  • 好! :-) 我不知道您在这里尝试实现的算法,所以很难确定。但是,我对rgb 进行总结看起来有点奇怪。也许您应该自己计算每个值,然后使用 int newPixel = 0xff000000 | (r &amp; 0xff) &lt;&lt; 16 | (g &amp; 0xff) &lt;&lt; 8 | (b &amp; 0xff); 重新创建打包的 RGB 格式?
  • 好吧,我正在尝试加密图像(Shamir 的秘密共享)/为此我必须运行一个函数,它将 R、G、B 值映射到一个值,即像素的颜色的加密图像。 (它们应该是类似灰色噪声的)。 func 是 = (R + G + B + a) mod prime。 [a 是随机数]。现在,这个函数要我对 RGB 值求和……很奇怪……所以我不能做你的方法……
  • 我明白了......好吧,我浏览了维基百科的文章,但它太技术性了,我无法在 30 秒内理解...... ;-) 所以我建议你专门问另一个问题。但是我看不到这种方法如何创建除了绿蓝色图像(如果prime 低于255,则为蓝色)。也许(val = func 的结果)int newPixel = 0xff000000 | (val &amp; 0xff) &lt;&lt; 16 | (val &amp; 0xff) &lt;&lt; 8 | (val &amp; 0xff); 那么呢?这至少应该会产生灰色噪声。或者你需要确保素数在 255 * 255 和 255 * 255 * 255 之间。这可以工作
猜你喜欢
  • 2015-12-23
  • 1970-01-01
  • 2021-12-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-14
  • 1970-01-01
相关资源
最近更新 更多