从C ++中的二进制一次读取4个字节

时间:2017-04-13 14:02:20

标签: c++

我试图从二进制文件一次读取4个字节。该文件已从512x512的图像转换为.bin。

文件结构的前4个字节为高度,后4个字节为宽度。然后文件的其余部分与其余像素的值相关联。

这是我为转换所做的代码,以防有人需要它:

package main;

import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import javax.imageio.ImageIO;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.filechooser.FileFilter;
import javax.swing.filechooser.FileNameExtensionFilter;

/**
 *
 * @author FFA
 */
public class Main {
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args){
        JFileChooser chooser = new JFileChooser();
        FileFilter filter = new FileNameExtensionFilter("Image File", ImageIO.getReaderFileSuffixes());
        chooser.setFileFilter(filter);
        chooser.showOpenDialog(null);
        File file = chooser.getSelectedFile();

        if(file == null) System.exit(0);
        File dest = new File(file.getParent(), file.getName().split("\\.")[0] + ".bin");
        dest.delete();
        try(FileOutputStream out = new FileOutputStream(dest, true)){
            BufferedImage image = ImageIO.read(file);
            int width = image.getWidth();
            int height = image.getHeight();
            byte[] data = new byte[width*height];
            int k = 0;

            byte[] widthData = ByteBuffer.allocate(4).putInt(width).array();
            byte[] heightData = ByteBuffer.allocate(4).putInt(height).array();
            out.write(widthData);
            out.write(heightData);

            for(int i=0; i<height;i++){
                for(int j=0; j<width; j++){
                    Color c = new Color(image.getRGB(j, i));

                    int grayValue = (int)Math.round(0.21*c.getRed() + 0.72*c.getGreen() + 0.07*c.getBlue());
                    data[k++] = (byte) grayValue;
                }
            }

            out.write(data);
            JOptionPane.showMessageDialog(null, "Conversion Done");
        }catch(IOException ex){
            JOptionPane.showMessageDialog(null, "Exception: "+ex);
        }
    }

}

测试图像为灰色Lena 512x512,因此只有灰度级。

整个计划是从图像转换为二进制 - >用C ++读取它,做一些操作,用二进制写,然后将其转换回图像。

如何在C ++中读取二进制文件,然后在C ++中执行卷积等操作?

我的计划在伪代码中是这样的:

read in 4 bytes
convert to local endian integer representation
assign to width
read in 4 bytes
convert to local endian integer representation
assign to height
for (row = 0; row < height; row++)
{
    add new row vector
    for (col = 0; col < width; col++)
    {
        read byte
        add to current row vector
    }
}

但我在将其翻译成C ++时遇到了一些问题。谁能给我一只手或一些提示?谢谢!

编辑:

#include <iostream>
#include <fstream>

int main() {

    FILE *fileptr;
    char *buffer;
    long filelen;

    fileptr = fopen("file.bin", "rb");  
    fseek(fileptr, 0, SEEK_END);          
    filelen = ftell(fileptr);             
    rewind(fileptr);                      

    buffer = (char *)malloc((filelen + 1) * sizeof(char)); 
    fread(buffer, filelen, 1, fileptr); 
    fclose(fileptr);

    system("Pause");
}

我认为这应该是读取每个字节的代码。要读取前4个字节,我需要从1读取到filelen / 128?

1 个答案:

答案 0 :(得分:0)

你可以在Windows上使用带有打开标志“r + b”或_open的fopen,或者Linux具有开放功能。

你还需要使用fread,fwrite和fclose与fopen,_read,_write和_close for Windows替代,或者读取,写入和关闭Linux版本。

如果你想让它可移植,你也可以编写自己的接口类。

这可以使用#ifdef _MSC_VER或#ifdef GNUC 来检测Linux gcc,尽管这是一种简化的方法,可以使您的解决方案可移植。

如果您希望使用标准C ++文件I / O库,也可以查看std :: fstream,这将为您提供免费的可移植性。

他们都有自己的优点和缺点。