简体   繁体   English

Java从像素矩阵创建BMP图像并反转

[英]java create BMP image from pixel matrix and reverse

Have a task to generate BMP file from int RGB matrix and than read that matrix from BMP image. 有一项任务是从int RGB矩阵生成BMP文件,然后从BMP图像读取该矩阵。

I've used this class to generate BMP file but it seems that it is hard to reverse this approach for getting rgbValues array from image: 我已经使用此类来生成BMP文件,但是似乎很难逆转这种从图像获取rgbValues数组的方法:

/**
 * Class for creating bmp images from the pixel matrix (an int matrix).
 * @author eafkuor
 * @link http://forum.codecall.net/topic/62457-creating-a-bmp-image-in-java/
 */
import java.io.File;
import java.io.FileOutputStream;

public class BMP {
    private final static int BMP_CODE = 19778;

    byte[] bytes;

    public void saveBMP(String filename, int[][] rgbValues) {
        try {
            FileOutputStream fos = new FileOutputStream(new File(filename));

            bytes = new byte[54 + 3 * rgbValues.length * rgbValues[0].length + getPadding(rgbValues[0].length) * rgbValues.length];

            saveFileHeader();
            saveInfoHeader(rgbValues.length, rgbValues[0].length);
            saveRgbQuad();
            saveBitmapData(rgbValues);

            fos.write(bytes);

            fos.close();

        } catch (Exception ignored) {}

    }

    private void saveFileHeader() {
        byte[] a = intToByteCouple(BMP_CODE);
        bytes[0] = a[1];
        bytes[1] = a[0];

        a = intToFourBytes(bytes.length);
        bytes[5] = a[0];
        bytes[4] = a[1];
        bytes[3] = a[2];
        bytes[2] = a[3];

        //data offset
        bytes[10] = 54;
    }

    private void saveInfoHeader(int height, int width) {
        bytes[14] = 40;

        byte[] a = intToFourBytes(width);
        bytes[22] = a[3];
        bytes[23] = a[2];
        bytes[24] = a[1];
        bytes[25] = a[0];

        a = intToFourBytes(height);
        bytes[18] = a[3];
        bytes[19] = a[2];
        bytes[20] = a[1];
        bytes[21] = a[0];

        bytes[26] = 1;

        bytes[28] = 24;
    }

    private void saveRgbQuad() {

    }

    private void saveBitmapData(int[][] rgbValues) {
        int i;

        for (i = 0; i < rgbValues.length; i++) {
            writeLine(i, rgbValues);
        }

    }

    private void writeLine(int row, int[][] rgbValues) {
        final int offset = 54;
        final int rowLength = rgbValues[row].length;
        final int padding = getPadding(rgbValues[0].length);
        int i;

        for (i = 0; i < rowLength; i++) {
            int rgb = rgbValues[row][i];
            int temp = offset + 3 * (i + rowLength * row) + row * padding;

            bytes[temp] = (byte) (rgb >> 16);
            bytes[temp + 1] = (byte) (rgb >> 8);
            bytes[temp + 2] = (byte) rgb;
        }
        i--;
        int temp = offset + 3 * (i + rowLength * row) + row * padding + 3;

        for (int j = 0; j < padding; j++)
            bytes[temp + j] = 0;

    }

    private byte[] intToByteCouple(int x) {
        byte[] array = new byte[2];

        array[1] = (byte) x;
        array[0] = (byte) (x >> 8);

        return array;
    }

    private byte[] intToFourBytes(int x) {
        byte[] array = new byte[4];

        array[3] = (byte) x;
        array[2] = (byte) (x >> 8);
        array[1] = (byte) (x >> 16);
        array[0] = (byte) (x >> 24);

        return array;
    }

    private int getPadding(int rowLength) {

        int padding = (3 * rowLength) % 4;
        if (padding != 0)
            padding = 4 - padding;


        return padding;
    }
}

Is there any java lib for making such things? 是否有用于制作此类东西的Java库? Or maybe someone can suggest how to reverse BMP file? 也许有人可以建议如何反转BMP文件?

Using an API is, in my opinion, a lazy thing to do, if the task is easy to implement AND you could get a better understanding of what is happening behind the scenes. 我认为,使用API​​是一件容易的事,如果该任务易于实现并且您可以更好地了解幕后情况。 After you have done it at least once yourself, you can use an API with a good conscience. 至少自己完成一次之后,您可以使用具有良心的API。 In the end you SHOULD use an API, because the working code is probably much powerful and safe to use than your own version. 最后,您应该使用API​​,因为工作代码可能比您自己的版本强大且安全。

Reversing an image is a very simple thing to do, in theory at least. 至少从理论上讲,反转图像是一件非常简单的事情。 The process consists of two steps: 该过程包括两个步骤:

  1. put the color matrix of the image into memory 将图像的颜色矩阵放入内存
  2. create a new image so that every pixel, starting from the left, is chosen from the image in memory, only starting from the right. 创建一个新图像,以便从内存中的图像中选择从左侧开始的每个像素,而仅从右侧开始。

To illustrate: 为了显示:

Say we have an image that is 4px in width and 4px in height. 假设我们有一个宽度为4px,高度为4px的图像。 0 indicates the pixel is black and 1 indicates it is white. 0表示像素为黑色,1表示像素为白色。

So we have, in practice, a 4x4 binary matrix. 因此,实际上,我们有一个4x4的二进制矩阵。 Let us compose it as follows: 让我们组成如下:

[1][0]
[1][0]

To reverse it, we simply copy the array into a new 4x4 matrix, but we copy the values to the new matrix starting from the right: 要反转它,我们只需将数组复制到一个新的4x4矩阵中,但是我们将从右边开始将值复制到新的矩阵中:

[1][0] => [0][1]
[1][0] => [0][1]

And now we have the reversed image: 现在,我们得到了相反的图像:

[0][1]
[0][1]

This is the idea. 这是主意。

In an RGB context, the matrix of the original image would look something like this: 在RGB上下文中,原始图像的矩阵如下所示:

[rgb(255, 255, 255)][rgb(0, 0, 0)]
[rgb(255, 255, 255)][rgb(0, 0, 0)]

Now go find out how to extract the color of each pixel and write it to a new one. 现在,了解如何提取每个像素的颜色并将其写入新的颜色。 This is an easy task. 这是一个容易的任务。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM