- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试更改图片中的像素(bmp 格式,24 位)。
我有这 3 个结构:
文件头:
#pragma pack(2)
typedef struct {
unsigned short int typeID;
unsigned int size;
unsigned short int reserved1, reserved2;
unsigned int offset;
}BITMAPFILEHEADER;
#pragma pack(0)
信息标题:
typedef struct {
unsigned int headerSize;
signed int widthPixel, heightPixel;
unsigned short int colorPlanes;
unsigned short int bitsPerPixel;
unsigned int compressionMethod;
unsigned int imagesize;
signed int xResolution, yResolution; // pixel per meter
unsigned int nbColor;
unsigned int importantColor;
}BITMAPINFOHEADER;
对于 RGB 颜色:
typedef struct {
unsigned char blue;
unsigned char green;
unsigned char red;
unsigned char reserved;
} RGBCOLOR;
然后是主要代码:
int main(void) {
BITMAPFILEHEADER fileHeader;
BITMAPINFOHEADER infoHeader;
FILE *inFileImage = NULL;
unsigned char *pBitsData = NULL;
int rowSize = 0;
int nImageSize = 0;
inFileImage = fopen("panda.bmp", "r+");
if (inFileImage == NULL)
{
fprintf(stderr, "Unable to open image");
return 0;
}
fread(&fileHeader, sizeof(BITMAPFILEHEADER), 1, inFileImage);
rewind(inFileImage);
pBitsData = (unsigned char *)calloc( fileHeader.size, sizeof(unsigned char) );
if( NULL == pBitsData )
{
printf("NO memory!!!!!\n");
}
else
{
fread(pBitsData, fileHeader.size * sizeof(unsigned char), 1, inFileImage);
memcpy(&fileHeader,pBitsData,sizeof(BITMAPFILEHEADER));
printf("Type ID: %x\n", fileHeader.typeID);
printf("File size: %d\n", fileHeader.size);
printf("Offset: %d\n", fileHeader.offset);
printf("**********************\n");
memcpy(&infoHeader, (pBitsData + sizeof(BITMAPFILEHEADER)), sizeof(BITMAPINFOHEADER));
printf("Header size: %u\n", infoHeader.headerSize);
printf("Width: %d\n", infoHeader.widthPixel);
printf("Height: %d\n", infoHeader.heightPixel);
printf("Nb planes: %d\n", infoHeader.colorPlanes);
printf("Bits per pixel: %d\n", infoHeader.bitsPerPixel);
printf("Compression method: %u\n", infoHeader.compressionMethod);
printf("Image size: %u\n", infoHeader.imagesize);
printf("Horizontal pixel per metre: %d\n", infoHeader.xResolution);
printf("Vertical pixel per metre: %d\n", infoHeader.yResolution);
printf("Number color in color table: %u\n", infoHeader.nbColor);
printf("Color important count: %u\n", infoHeader.importantColor);
printf("**********************\n");
rowSize = ((infoHeader.bitsPerPixel * infoHeader.widthPixel + 31) / 32) * 4;
printf("Row Size: %d\n", rowSize);
nImageSize = rowSize * abs(infoHeader.heightPixel);
printf("Pixel Array Size: %d\n", nImageSize);
printf("**********************\n");
RGBCOLOR* pixelData = (RGBCOLOR*)(pBitsData + fileHeader.offset);
// M is define with the value 5 - the 5 pixel from image
printf("Pixel %x, %x, %x\n", pixelData[M].blue, pixelData[M].green, pixelData[M].red);
//fseek(inFileImage, fileHeader.offset, SEEK_CUR);
//fread(pixelData, sizeof(RGBCOLOR), 1, inFileImage);
pixelData[M].red = 0x00;
pixelData[M].blue = 0xef;
pixelData[M].green = 0x00;
//memcpy((pBitsData + fileHeader.offset), &pixelData, sizeof(RGBCOLOR)); // <= here seems to be my problem
//fwrite(pixelData, sizeof(RGBCOLOR), 1, inFileImage); // how can i copy to image from a memory
printf("Pixel %x, %x, %x\n", pixelData[M].blue, pixelData[M].green, pixelData[M].red);
}
fclose(inFileImage);
if(NULL != pBitsData)
{
free(pBitsData);
}
return 0;
}
我想更改图像中的第五个像素(其中之一:蓝色->红色、绿色->蓝色等)。你能告诉我我的代码哪里有错误吗?我怎样才能改变我的代码才能正常工作?谢谢
编辑:
而不是
RGBCOLOR* pixelData = (RGBCOLOR*)(pBitsData + fileHeader.offset);
// M is define with the value 5 - the 5 pixel from image
printf("Pixel %x, %x, %x\n", pixelData[M].blue, pixelData[M].green, pixelData[M].red);
//fseek(inFileImage, fileHeader.offset, SEEK_CUR);
//fread(pixelData, sizeof(RGBCOLOR), 1, inFileImage);
pixelData[M].red = 0x00;
pixelData[M].blue = 0xef;
pixelData[M].green = 0x00;
//memcpy((pBitsData + fileHeader.offset), &pixelData, sizeof(RGBCOLOR)); // <= here seems to be my problem
//fwrite(pixelData, sizeof(RGBCOLOR), 1, inFileImage); // how can i copy to image from a memory
printf("Pixel %x, %x, %x\n", pixelData[M].blue, pixelData[M].green, pixelData[M].red);
如果我写
RGBCOLOR img;
fseek(inFileImage, fileHeader.offset, SEEK_SET);
img.blue = 0x00;
img.green = 0x00;
img.red = 0xff;
fwrite(&img, sizeof(RGBCOLOR), 1, inFileImage);
这将更改第一个像素。但我想复制到内存中,并从那里更改像素。
最佳答案
我使用 MinGW,因此您需要更改用于结构对齐的#pragma
。这是一个一体化的来源,可以
为了简洁起见,我没有费心进行任何错误检查。我已经用 24/32 位图像对其进行了测试。与 32 位图像一起使用时,它不会输出有效图像。
首先,这是之前和之后的图像。图像本身为 2x2 像素,为了清晰起见,我只是将其放大了。
之前:
之后:
如果仔细观察,您会发现两个图像之间唯一不同的字节是文件中 0x3E 处的字节。我们已将红色像素 (00 00 FF) 更改为紫色像素 (FF 00 FF)。由于图像是自下而上的,因此像素数据的前 3 个字节用于黄色像素,接下来的 3 个字节用于蓝色像素,后面是 2 个字节的填充,然后我们有 3 个用于红色,3 个用于绿色,另外 2 个填充字节。
以下是进行更改的代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef WORD
#define WORD unsigned short
#endif
#ifndef DWORD
#define DWORD unsigned long
#endif
#ifndef BYTE
#define BYTE unsigned char
#endif
#ifndef LONG
#define LONG long
#endif
#define minGW 1
#ifdef minGW
#pragma pack(push,2)
#endif
typedef struct tagBITMAPFILEHEADER {
WORD bfType;
DWORD bfSize;
WORD bfReserved1;
WORD bfReserved2;
DWORD bfOffBits;
} BITMAPFILEHEADER,*LPBITMAPFILEHEADER,*PBITMAPFILEHEADER;
#ifdef minGW
#pragma pack(pop)
#endif
typedef struct tagBITMAPINFOHEADER{
DWORD biSize;
LONG biWidth;
LONG biHeight;
WORD biPlanes;
WORD biBitCount;
DWORD biCompression;
DWORD biSizeImage;
LONG biXPelsPerMeter;
LONG biYPelsPerMeter;
DWORD biClrUsed;
DWORD biClrImportant;
} BITMAPINFOHEADER,*LPBITMAPINFOHEADER,*PBITMAPINFOHEADER;
typedef struct tagRGBQUAD
{
BYTE rgbBlue;
BYTE rgbGreen;
BYTE rgbRed;
BYTE rgbReserved;
} RGBQUAD,*LPRGBQUAD;
typedef struct tagBITMAPINFO
{
BITMAPINFOHEADER bmiHeader;
RGBQUAD bmiColors[1];
} BITMAPINFO,*LPBITMAPINFO,*PBITMAPINFO;
typedef struct tagBITMAP
{
BITMAPINFOHEADER bmInfo;
unsigned char *pBits;
} BITMAP, *PBITMAP;
PBITMAP readBitmapFile(const char *filename)
{
FILE *fp;
PBITMAP result;
BITMAPFILEHEADER fileHeader;
BITMAPINFO bmpInfo;
fp = fopen(filename, "rb");
fread(&fileHeader, sizeof(BITMAPFILEHEADER), 1, fp);
fread(&bmpInfo, sizeof(BITMAPINFO), 1, fp);
fseek(fp, fileHeader.bfOffBits, SEEK_SET);
unsigned char *pBits = (unsigned char *)calloc(bmpInfo.bmiHeader.biSizeImage, sizeof(unsigned char) );
fread(pBits, sizeof(char), bmpInfo.bmiHeader.biSizeImage, fp);
fclose(fp);
result = (PBITMAP) calloc(1, sizeof(*result) );
memcpy(&result->bmInfo, &bmpInfo, sizeof(bmpInfo) );
result->pBits = pBits;
return result;
}
void saveBitmapFile(const char *filename, PBITMAP img)
{
FILE *fp;
BITMAPFILEHEADER fileHeader;
memset(&fileHeader, 0, sizeof(fileHeader));
fileHeader.bfType = 0x4d42; //'BM'
fileHeader.bfOffBits = sizeof(BITMAPINFOHEADER) + sizeof(BITMAPFILEHEADER);
fileHeader.bfSize = fileHeader.bfOffBits + (img->bmInfo.biSizeImage);
fp = fopen(filename, "wb");
fwrite(&fileHeader, sizeof(fileHeader), 1, fp);
fwrite(&img->bmInfo, sizeof(img->bmInfo), 1, fp);
fwrite(img->pBits, 1, img->bmInfo.biSizeImage, fp);
fclose(fp);
}
void myPixel(int x, int y, char r, char g, char b, PBITMAP image)
{
unsigned char *ptrToPixel;
int rowSize = ((image->bmInfo.biBitCount * image->bmInfo.biWidth + 31) / 32) * 4;
int curRow, bytesPerPixel;
if (image->bmInfo.biHeight < 0)
{
curRow = y;
}
else if (image->bmInfo.biHeight > 0)
{
curRow = (image->bmInfo.biHeight-1) - y;
}
bytesPerPixel = image->bmInfo.biBitCount / 8;
ptrToPixel = (curRow * rowSize) + (x*bytesPerPixel) + image->pBits;
ptrToPixel[0] = b;
ptrToPixel[1] = g;
ptrToPixel[2] = r;
}
int main()
{
PBITMAP inImage = readBitmapFile("colorTile.bmp");
myPixel(0,0, 255,0,255, inImage);
saveBitmapFile("colorTileOut.bmp", inImage);
}
编辑:看完Can someone provide me a specification of 32 bit BMP image format?和 https://forums.adobe.com/message/3272950#3272950很明显,32 位位图使用的是 V3 header - 该 header 包含 4 个长整型来指定 4 个 channel 中每个 channel 的位掩码。随后,我修改了 saveBitmapFile
和 myPixel
例程,并且可以确认代码现在似乎也可以在 32 位位图上正常运行。
void saveBitmapFile(const char *filename, PBITMAP img)
{
FILE *fp;
BITMAPFILEHEADER fileHeader;
unsigned long maskArray[] = {0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF};
memset(&fileHeader, 0, sizeof(fileHeader));
fileHeader.bfType = 0x4d42; //'BM'
fileHeader.bfOffBits = sizeof(BITMAPINFOHEADER) + sizeof(BITMAPFILEHEADER);
if (img->bmInfo.biBitCount == 32)
fileHeader.bfOffBits += sizeof(maskArray);
fileHeader.bfSize = fileHeader.bfOffBits + (img->bmInfo.biSizeImage);
fp = fopen(filename, "wb");
fwrite(&fileHeader, sizeof(fileHeader), 1, fp);
fwrite(&img->bmInfo, sizeof(img->bmInfo), 1, fp);
if (img->bmInfo.biBitCount == 32)
fwrite(&maskArray, sizeof(long), 4, fp);
fwrite(img->pBits, 1, img->bmInfo.biSizeImage, fp);
fclose(fp);
}
void myPixel(int x, int y, char r, char g, char b, PBITMAP image)
{
unsigned char *ptrToPixel;
int rowSize = ((image->bmInfo.biBitCount * image->bmInfo.biWidth + 31) / 32) * 4;
int curRow, bytesPerPixel;
if (image->bmInfo.biHeight < 0)
{
curRow = y;
}
else if (image->bmInfo.biHeight > 0)
{
curRow = (image->bmInfo.biHeight-1) - y;
}
bytesPerPixel = image->bmInfo.biBitCount / 8;
ptrToPixel = (curRow * rowSize) + (x*bytesPerPixel) + image->pBits;
if (image->bmInfo.biBitCount == 24)
{
ptrToPixel[0] = b;
ptrToPixel[1] = g;
ptrToPixel[2] = r;
}
else if (image->bmInfo.biBitCount == 32)
{
// ptrToPixel[0] = a;
ptrToPixel[1] = b;
ptrToPixel[2] = g;
ptrToPixel[3] = r;
}
}
关于c - 关于 BMP 文件。我如何写入/更改像素颜色? (在C中),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31608867/
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
我是一名优秀的程序员,十分优秀!