【发布时间】:2016-04-15 03:18:39
【问题描述】:
感谢您的帮助。这是最终版本。 工作版本
BMPHead.znak1='B';
BMPHead.znak2='M';
BMPHead.bfSize=40;
BMPHead.bfReserved1 = 0;
BMPHead.bfReserved1 = 0;
BMPHead.bfOffBits=54;
BMPHead.biSize=40;
BMPHead.biWidth=CSVHead.depth_pxsize ;
BMPHead.biHeight=CSVHead.lateral_pxsize;
BMPHead.biPlanes=1;
BMPHead.biBitCount=32;
BMPHead.biCompression = 0;
BMPHead.biSizeImage = ((CSVHead.lateral_pxsize * CSVHead.depth_pxsize)*4);
BMPHead.biXPelsPerMeter = 0;
BMPHead.biYPelsPerMeter = 0;
BMPHead.biClrUsed = 0;
BMPHead.biClrImportant =0;
void zamiana_danych(int &EndOfHead, float line[], csvh &CSVHead, bmph BMPHead, float &max, float &min)
{ unsigned char bit_empty=0;
float tmp[500];
ifstream obraz;
fstream bitmapa("POP_OCT.bmp");
obraz.open("POP_OCT.csv", ios::binary);
obraz.seekg(EndOfHead, ios_base::beg);
bitmapa.seekg(BMPHead.bfOffBits, ios_base::beg); // this part was missing
for( int numb=0; numb < CSVHead.depth_pxsize; numb++ )
{
//wczytanie jednego wiersza dancyh
for(int i=0; i<CSVHead.lateral_pxsize; i++)
{ //wczytanie komorki danych
obraz>>line[i];
obraz.seekg(+1, ios_base::cur);
tmp[i]=((max-min) / 255) * line[i] - min;
unsigned char pixel[4]={tmp[i],tmp[i],tmp[i],0};
bitmapa.write((char*)&pixel, sizeof(pixel));
}
}
bitmapa.close();
obraz.close();
问题 我需要在不使用非标准库的情况下在 C++ 中创建 BMP,但我仍然有一些错误。我知道有一些类似的主题,但我仍然不清楚如何使这件事发挥作用。
文件已创建,但当我尝试打开它时,照片浏览器显示:
“Windows Image Viewer 无法打开图像,因为文件太大或损坏”。
我不确定问题出在标题还是像素写入中。
代码如下:
#include<iostream>
#include<fstream>
#include<cstring>
#include <stdlib.h>
using namespace std;
struct bmph{
unsigned short int bfType; // instead of this I use znak1 and znak2
unsigned long int bfSize;
unsigned short int bfReserved1;
unsigned short int bfReserved2;
unsigned long int bfOffBits;
unsigned long int biSize;
unsigned long int biWidth;
unsigned long int biHeight;
unsigned short int biPlanes;
unsigned short int biBitCount;
unsigned long int biCompression;
unsigned long int biSizeImage;
unsigned long int biXPelsPerMeter;
unsigned long int biYPelsPerMeter;
unsigned long int biClrUsed;
unsigned long int biClrImportant;
};
int main()
{
unsigned char pixel[4]={255,255,255,0};
char znak1='B';
char znak2='M';
bmph bmpheader;
ofstream moje_bmp("tworzBMP.bmp");
bmpheader.bfSize=40 + (500*999)*4;
bmpheader.bfReserved1 = 0;
bmpheader.bfReserved1 = 0;
bmpheader.bfOffBits=54;
bmpheader.biSize=40;
bmpheader.biWidth=500;
bmpheader.biHeight=999;
bmpheader.biPlanes=1;
bmpheader.biBitCount=4;
bmpheader.biCompression = 0;
bmpheader.biSizeImage = (500*999)*4;
bmpheader.biXPelsPerMeter = 0;
bmpheader.biYPelsPerMeter = 0;
bmpheader.biClrUsed = 0;
bmpheader.biClrImportant =0;
moje_bmp << znak1 <<znak2;
moje_bmp.write((char*)&bmpheader.bfSize, sizeof(bmpheader.bfSize));
moje_bmp.write((char*)&bmpheader.bfReserved1, sizeof(bmpheader.bfReserved1));
moje_bmp.write((char*)&bmpheader.bfReserved1, sizeof(bmpheader.bfReserved1));
moje_bmp.write((char*)&bmpheader.bfOffBits, sizeof(bmpheader.bfOffBits));
moje_bmp.write((char*)&bmpheader.bfSize, sizeof(bmpheader.bfSize));
moje_bmp.write((char*)&bmpheader.biWidth, sizeof(bmpheader.biWidth));
moje_bmp.write((char*)&bmpheader.biHeight, sizeof(bmpheader.biHeight));
moje_bmp.write((char*)&bmpheader.biPlanes, sizeof(bmpheader.biPlanes));
moje_bmp.write((char*)&bmpheader.biBitCount, sizeof(bmpheader.biBitCount));
moje_bmp.write((char*)&bmpheader.biCompression, sizeof(bmpheader.biCompression));
moje_bmp.write((char*)&bmpheader.biSizeImage, sizeof(bmpheader.biSizeImage));
moje_bmp.write((char*)&bmpheader.biXPelsPerMeter, sizeof(bmpheader.biXPelsPerMeter));
moje_bmp.write((char*)&bmpheader.biYPelsPerMeter, sizeof(bmpheader.biYPelsPerMeter));
moje_bmp.write((char*)&bmpheader.biClrUsed, sizeof(bmpheader.biClrUsed));
moje_bmp.write((char*)&bmpheader.biClrImportant, sizeof(bmpheader.biClrImportant));
for(int tx=0; tx<500;tx++)
{
for(int ty=0; ty<999;ty++)
{
moje_bmp.write((char*)&pixel, sizeof(pixel));
}
}
moje_bmp.close();
return 0;
}
在上面的示例中所有这些都有效,但在我的主项目中却没有。以下是主项目中的功能和相同的结果: “Windows Image Viewer 无法打开图像,因为文件太大或损坏”。
void glowa_bmp(bmph &BMPHead, csvh &CSVHead)
{
ofstream bitmapa("bitmapa.bmp", ios::binary);
//przypisanie wartosci naglowka
BMPHead.znak1='B';
BMPHead.znak2='M';
BMPHead.bfSize=54;
BMPHead.bfReserved1 = 0;
BMPHead.bfReserved1 = 0;
BMPHead.bfOffBits=54;
BMPHead.biSize=40;
BMPHead.biWidth=CSVHead.depth_pxsize ;
BMPHead.biHeight=CSVHead.lateral_pxsize;
BMPHead.biPlanes=1;
BMPHead.biBitCount=32;
BMPHead.biCompression = 0;
BMPHead.biSizeImage = ((CSVHead.lateral_pxsize * CSVHead.depth_pxsize)*4);
BMPHead.biXPelsPerMeter = 0;
BMPHead.biYPelsPerMeter = 0;
BMPHead.biClrUsed = 0;
BMPHead.biClrImportant =0;
//zapisanie naglowka w pliku
bitmapa << BMPHead.znak1 << BMPHead.znak2;
bitmapa.write((char*)&BMPHead.bfSize, sizeof(BMPHead.bfSize));
bitmapa.write((char*)&BMPHead.bfReserved1, sizeof(BMPHead.bfReserved1));
bitmapa.write((char*)&BMPHead.bfReserved1, sizeof(BMPHead.bfReserved1));
bitmapa.write((char*)&BMPHead.bfOffBits, sizeof(BMPHead.bfOffBits));
bitmapa.write((char*)&BMPHead.bfSize, sizeof(BMPHead.bfSize));
bitmapa.write((char*)&BMPHead.biWidth, sizeof(BMPHead.biWidth));
bitmapa.write((char*)&BMPHead.biHeight, sizeof(BMPHead.biHeight));
bitmapa.write((char*)&BMPHead.biPlanes, sizeof(BMPHead.biPlanes));
bitmapa.write((char*)&BMPHead.biBitCount, sizeof(BMPHead.biBitCount));
bitmapa.write((char*)&BMPHead.biCompression, sizeof(BMPHead.biCompression));
bitmapa.write((char*)&BMPHead.biSizeImage, sizeof(BMPHead.biSizeImage));
bitmapa.write((char*)&BMPHead.biXPelsPerMeter, sizeof(BMPHead.biXPelsPerMeter));
bitmapa.write((char*)&BMPHead.biYPelsPerMeter, sizeof(BMPHead.biYPelsPerMeter));
bitmapa.write((char*)&BMPHead.biClrUsed, sizeof(BMPHead.biClrUsed));
bitmapa.write((char*)&BMPHead.biClrImportant, sizeof(BMPHead.biClrImportant));
bitmapa.close();
}
void zamiana_danych(int &EndOfHead, float line[], csvh &CSVHead, float &max, float &min)
{ unsigned char bit_empty=0;
float tmp[500];
ifstream obraz;
ofstream bitmapa("bitmapa.bmp", ios::binary);
obraz.open("POP_OCT.csv", ios::binary);
obraz.seekg(EndOfHead, ios_base::beg);
for( int numb=0; numb < CSVHead.depth_pxsize; numb++ )
{
//wczytanie jednego wiersza dancyh
for(int i=0; i<CSVHead.lateral_pxsize; i++)
{ //wczytanie komorki danych
obraz>>line[i];
obraz.seekg(+1, ios_base::cur);
tmp[i]=((max-min) / 255) * line[i] - min;
unsigned char pixel[4]={tmp[i],tmp[i],tmp[i],0};
bitmapa.write((char*)&pixel, sizeof(pixel));
}
}
bitmapa.close();
obraz.close();
}
【问题讨论】:
-
你没有设置,也没有写
bfReserved2。这可能不是问题,因为您要写两次bfReserved1。但这是“错误的”。你的编译器中的sizeof(long)是什么? -
BMPHead.bfSize=54;仍然是错误的。请参阅我的答案 + cmets :) - 它必须是文件的总大小。 -
@Danny_ds 应该是这样,但它是这样工作的......不知道如何
-
@Artur - 可能取决于软件(例如,某些软件可以使用文件长度而不是此字段,但值应该是正确的)。但是我的评论是针对您编辑的答案:在上面的示例中所有这些都有效,但在我的主项目中却没有。