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

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

本文介绍了Java从像素矩阵创建BMP图像并反转的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有一项任务是从int RGB矩阵生成BMP文件,然后从BMP图像读取该矩阵.

Have a task to generate BMP file from int RGB matrix and than read that matrix from BMP image.

我已经使用此类来生成BMP文件,但是似乎很难逆转这种从图像获取rgbValues数组的方法:

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:

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

是否存在用于制作此类东西的Java库?也许有人可以建议如何反转BMP文件?

Is there any java lib for making such things? Or maybe someone can suggest how to reverse BMP file?

推荐答案

使用API​​是一件很懒的事情,如果该任务易于实现并且您可以更好地了解正在发生的事情在幕后.至少自己完成一次之后,就可以使用具有良好意识的API.最后,应该使用一个API,因为工作代码可能比您自己的版本更强大和安全.

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. After you have done it at least once yourself, you can use an API with a good conscience. In the end you SHOULD use an API, because the working code is probably much powerful and safe to use than your own version.

至少从理论上讲,反转图像是一件非常简单的事情.该过程包括两个步骤:

Reversing an image is a very simple thing to do, in theory at least. The process consists of two steps:

  1. 将图像的颜色矩阵放入内存
  2. 创建新图像,以便从内存中的图像中选择从左侧开始的每个像素,而仅从右侧开始.


说明:


To illustrate:

假设我们有一个宽度为4像素,高度为4像素的图像.0表示像素为黑色,1表示像素为白色.

Say we have an image that is 4px in width and 4px in height.0 indicates the pixel is black and 1 indicates it is white.

因此,实际上,我们有一个4x4的二进制矩阵.让我们组成如下:

So we have, in practice, a 4x4 binary matrix. Let us compose it as follows:

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

要反转它,我们只需将数组复制到一个新的4x4矩阵中,但是我们从右开始将值复制到新的矩阵中:

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:

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

现在我们得到了反转的图像:

And now we have the reversed image:

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

这是主意.

在RGB上下文中,原始图像的矩阵看起来像这样:

In an RGB context, the matrix of the original image would look something like this:

[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.

这篇关于Java从像素矩阵创建BMP图像并反转的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-31 06:36