【问题标题】:Java BufferedImage: How do i copy an image properly n times by accessing the pixel - array?Java BufferedImage:如何通过访问像素数组正确复制图像 n 次?
【发布时间】:2020-10-23 13:38:08
【问题描述】:

我正在处理我正在处理的项目中“分叉”的问题。没有必要为项目本身解决问题,但我提到了起源,因为它是一种“奇怪的特定”任务。

我正在尝试从文件(8x8 像素)中读取一个小的 BufferedImage。 该图像的像素被写入一个整数数组,长度为 64(显然)。

然后,创建一个长度为 64*64 (=4096) 的新数组。小数组的像素被复制到大数组中 64 次,每次到达末尾都将较小的索引重置为 0。

最后,我创建了一个宽度 = 64 和高度 = 64 的新 BufferedImage。然后将大数组设置为所述 BufferedImage 的 rgbArray。代码如下:

public static void main(String[] args)throws IOException {
    
    BufferedImage toCopy = ImageIO.read(new File("smallStripes.png"));
    BufferedImage copiedNTimes = new BufferedImage(64, 64, BufferedImage.TYPE_BYTE_BINARY); 
    //copiedNTimes is to be the resulting image

    Graphics2D g2d = (Graphics2D) copiedNTimes.getGraphics();
    g2d.setColor(Color.WHITE);
    g2d.fillRect(0, 0, 64, 64);

    int[] smallPixels = new int[64];

    toCopy.getRGB(0, 0, 8, 8, smallPixels, 0, 8);
    //copy the rgb array of read image into the 64 - array

    int[] copied = copyNTimes(smallPixels, new int[64*64]);

    copiedNTimes.setRGB(0, 0, 64, 64, copied, 0, 8);
    //setting the rgb array of result image to the copied one

    FileOutputStream fos = new FileOutputStream(new File("result.png"));
    ImageIO.write(copiedNTimes, "png", fos);
}

static int[] copyNTimes(int[] small, int[] big){

    //this method copies the small array into the larger one
    //until the larger one is 'filled up'

    int index = 0;

    for(int x = 0 ; x < big.length; x++){
        big[x] = small[index];
        index++;
        if(index == small.length)
            index = 0;
    }

    return big;
}

它或多或少像我预期的那样工作,但图像被写成“移位”:

smallStripes.png:

结果.png:

我的问题是:

我怎样才能使条纹相互“对齐”?现在它是,从左到右,8px 黑色,8px 白色,8px 黑色......等等。 为什么不是 64 px 黑色(新线) 64 px 白色(新线)等?

正如已经说过的,它非常具体且过于简单,因此我可以更好地描述它。

【问题讨论】:

  • 您是要复制图像还是放大图像?换句话说,你是要复制每个像素 64 次,还是要复制 64 个像素 64 次?
  • 我的目标是将小 8x8 图像彼此相邻放置,每行 8 张图像,共 8 列。这是因为它最初不是照片图像,而是可扫描的代码光栅。发布的解决方案对我来说效果很好,无论如何感谢您的评论!

标签: java arrays pixel bufferedimage


【解决方案1】:

您的代码使用 scanline=8 作为 setRGB 的最后一个参数,并且 copyNTimes 中的错误逻辑会导致您的剥离效果。如果您希望将 8x8 像素图像重复为 64x64 像素图像作为 8x8 块,请用此替换您的 setRGB 调用以将小图像重复为较大的图像:

for (int x = 0 ; x < 64 ; x += 8)
    for (int y = 0 ; y < 64 ; y += 8)
        copiedNTimes.setRGB(x, y, 8, 8, smallPixels, 0, 8);

或者用这个替换你的 setRGB 调用,首先构建更大的 int[] 并一步应用它:

copiedNTimes.setRGB(0, 0, 64, 64, copied, 0, 64);

static int[] copyNTimes(int[] small, int[] big){
    for(int x = 0 ; x < big.length; x++){
        big[x] = small[8 * ((x / 64) % 8) + (x % 8)];
    }
    return big;
}

【讨论】:

  • 成功了!原来我不明白数组是如何构建的。扫描线大小最初是 64,这当然无助于纠正我错误的复制方法。非常感谢,这让我很困扰,我不想承认。
猜你喜欢
  • 1970-01-01
  • 2013-12-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-13
相关资源
最近更新 更多