c++ BGR图像的灰度转换给出损坏的图像

xqk2d5yq  于 2024-01-09  发布在  其他
关注(0)|答案(1)|浏览(188)

我试图转换BGR位图图像灰度使用的代码,

  1. int main()
  2. {
  3. FILE* fIn;
  4. FILE* fOut;
  5. if (fopen_s(&fIn, "D:\\VBox\\Shared\\images\\sample01.bmp", "rb") != 0) {
  6. return 1;
  7. }
  8. if (fopen_s(&fOut, "D:\\VBox\\Shared\\images\\sample01_gs1.bmp", "wb") != 0) {
  9. return 1;
  10. }
  11. unsigned char info[54];
  12. fread(info, sizeof(unsigned char), 54, fIn); // read the 54-byte header
  13. int32_t width, height;
  14. uint16_t bitperpixl;
  15. memcpy(&width, info + 18, sizeof(int32_t));
  16. memcpy(&height, info + 22, sizeof(int32_t));
  17. memcpy(&bitperpixl, info + 28, sizeof(uint16_t));
  18. int padding = ((width * bitperpixl) / 8) % 4; // which Is 0 for the image which I am using.
  19. fwrite(info, sizeof(unsigned char), 54, fOut);
  20. unsigned char pixel[3]; //bgr
  21. for (int y = 0; y < height; ++y)
  22. {
  23. for (int x = 0; x < width; ++x)
  24. {
  25. fread(pixel, 3, 1, fIn);
  26. unsigned char gray = pixel[2] * 0.3 + pixel[1] * 0.58 + pixel[0] * 0.11;
  27. memset(pixel, gray, sizeof(pixel));
  28. fwrite(&pixel, 3, 1, fOut);
  29. }
  30. fread(pixel, padding, 1, fIn);
  31. fwrite(pixel, padding, 1, fOut);
  32. }
  33. fclose(fOut);
  34. fclose(fIn);
  35. }

字符串
创建的文件与输入图像大小相同。当我尝试使用Windows图像查看器或pain打开文件时,它显示图像不支持或已损坏。

i2byvkas

i2byvkas1#

你的代码有几个重要的问题。首先,你不应该假设位图图像数据总是从字节54开始。维基百科的"BMP文件格式"文章的文件结构部分以
位图图像文件由固定大小的结构(标题)以及以预定顺序出现的可变大小的结构组成。由于这种文件格式的长期演变,其中一些结构的许多不同版本可以出现在文件中。
然后有一个图表显示了在实际像素阵列之前出现的可选或半可选部分。相反,如位图文件头部分所示,像素数据开始位置是偏移量为10的4个字节,因此您应该有几行,如

  1. uint32_t pixelData;
  2. memcpy(&pixelData, info + 10, sizeof(pixelData));

字符串
当然,在处理像素时,您将从该位置开始阅读。
此外,关于处理像素数据本身,请注意,您不能假设它们都是4字节块,每个块的前3个字节是RGB值,然后是填充字节。(例如,其中值是该表的偏移量)。此外,如果正在使用Windows BITMAPINFOHEADER,然后在偏移量30处有一个4字节的值,表示正在使用的压缩方法。Wikipedia文章描述了各个位表示什么,因此,您的代码需要如何解释像素值。
如果你能确定输入的. bmp文件是一组特定的有限格式之一,你可以编写代码来处理这些类型的文件。否则,你应该处理所有这些不同的额外细节。请注意,虽然BMP文件格式实际上基本上是最简单的图像格式,但仍然有很多事情需要检查和处理,以处理所有情况。
还有一个更普遍的问题是,从头开始编写自己的代码来读取BMP文件并将图像数据转换为灰度的目的是什么。如果是为了自己的个人教育,那么只需使用我给予的信息,以及维基百科文章中的其他细节,就足以让您获得一个工作程序(尽管正确处理所有各种选项需要花费相当多的时间和代码)。
否则,由于BMP文件格式已经存在了很长时间,以及它是如何相对常见,有多个免费的,和许多商业,程序,允许您读取BMP文件,并对其内容进行各种调整,如你试图做什么。
或者,有各种开源代码图像库,您至少可以检查以获得一些想法。例如,10 Best Open Source Image Processing Libraries提供了一个很好的列表。请注意,ImageMagick是AFAIK最古老和最流行的一个,尽管其他好的检查包括VIPSOpenCV
此外,还有免费的类,库等,至少可以减少您需要做的工作量。C++: What's the simplest way to read and write BMP files using C++ on Windows?中提供了BMP文件的一些建议,C++ Image Processing Libraries中提供了多种图像类型。

展开查看全部

相关问题