C文件处理之24/32位bmp图像的旋转

用C操作的24/32位bmp图像旋转

引入——

  写作本帖以纪念初步解锁位图bmp格式!
  本文的目的是通过程序从原有24或32位bmp位图文件生成顺时针旋转90°的新文件。由于涉及课程作业,本文不贴代码,只记录处理要点。

  主要参考资料为BMP24位位图格式总结 - 百度文库相关论坛问题下7楼cht_1988的回答

0.背景

  bmp是一种Windows系统下通用的图片格式,我们可以通过画图软件生成(PS甚至Windows自带的"画图"就行)。
  位图的一个重要属性——位数,其更专业的名称叫色深,一般有2,8,16,24,32等。
  先来了解一下BMP图像文件,即位图的构成。

  典型的BMP图像文件由四部分组成:

  ①位图头文件数据结构,也叫文件头。它包含BMP图像文件的类型、显示内容等信息;

  ②位图信息数据结构,信息头。它包含有BMP图像的宽、高、压缩方法,以及定义颜色等信息;

  ③调色板,这个部分是可选的,有些位图需要调色板,有些位图,比如真彩色图(24位的BMP)和32位BMP就不需要调色板;

  ④位图数据,这部分的内容根据BMP位图使用的位数不同而有区别。
     在24位图中直接使用RGB(每个像素依次用BGR3个字节表示),而其他的小于24位的使用调色板中颜色索引值。
     32位位图每个像素用ABGR4个字节表示,A是透明度(通道),(我处理的图片里)多数情况为零。
     这些字节的排列顺序非常重要,因为文件显示时可能是按固定的格式读取的(瞎猜的x),如果搞错,在后面转换时就有可能喜提一张加滤镜的照片(真的√)。
     此处还没说清具体的顺序,先卖个关子,待后文分析。

  此外,位图一般不进行压缩,没有"加密",可以直接处理,所以占用储存空间也较大。

1.借别人的Demo快速看懂BMP文件结构

  学习资料:相关论坛问题下7楼cht_1988的回答(代码)。
  这堆代码要干的事呢,就是根据现有的BMP,直接原模原样生成另一个copy。
  这位大哥的注释超详尽,唯恐大家看不懂BMP haha。这份代码真的对接触bmp非常有用!But……

  计划总是没有变化快,我现有的BMP图像文件里竟有一个32位图在转换后出现了缺失一种颜色的bug,比如图片白色的部分变成了黄色。
  这个问题其实直到我下载了WinHex一探文件内部究竟后才解决。且见下文分解!

2.利用WinHex一探文件内部究竟

  学习资料:BMP24位位图格式总结 - 百度文库
  我们现在要做的就是真实面对文件里写的16进制码,即"从计算机的视角"打开BMP格式文件,有很多软件都可以做到这一点。比如WinHex,据说Visual Studio和Vscode+插件也可以。
  WinHex也算是良心软件了,居然占用空间那么小就解决了我目前的燃眉之急。(不像VS)

3.旋转操作

  顺时针旋转90°并不难实现,关键要理解那些字节在BMP里存储的方式和顺序。我用的方法比较笨,循环遍历+单字节写入。
  存储的顺序是从一张图片的左下角到右上角,即从左到右、自下而上。
  存储方式如下图由C到B,旋转后首先图片的长宽会改变,并且先以D-B-C-A的顺序写入。


4.Bug1——运行32位图像程序会崩溃

  这个bug发生在我看上面那篇百度文档和下载WinHex前。原因就是32位图片的信息头比24位多了84位(不一定都是84位,要根据文件的信息头的前四个字节算)。我单独读取了这些字节并写入文件就好了,此处略过。

5.Bug2——32位颜色缺失

  这个bug主要因为我处理的32位图片的信息区域是以ABGR的顺序储存像素信息的,跟网上资料介绍的BGRA顺序不一样。
  于是我没思考那么多,立刻改了写入顺序,这张32位图也由黄色重新被洗白啦。
  于是出现下一个bug。exm???

6.Bug3——又来颜色缺失?

  打开的下一张32位图片由白变蓝了?!再次用WinHex打开,结果让我哭笑不得……
  这张图像素的储存顺序居然是BGRA…
  我加了一个判断,即如果第一个像素点的第一个字节为0,默认它就是A通道,是按ABGR储存的;反之,是BGRA。
  其实算是有冒险成分在里面的吧(但是这是我目前最好最简便的办法了)。
  就这样解决了。

6.Bug4——关于补齐4倍数的字节

  读取BMP的扫描行要求每行存放4的整数倍个字节。在这里我把要补的字节数忘记更新了,赶在ddl前返工的滋味可不太好受啊
  不过问题得到解决的快乐是无可比拟的,xixi[呲牙]

结语——

  写到这里,我脑中忽然闪过一念,在bug2那里,也许是我把某个字节漏读了、导致BGRA读成了ABGR?但是这样解释不了不同图像之间的差异啊……
  困惑ing……
  所以真心希望看到这篇文章的同学们能比我更进一步,看看这个bug到底是不是bug,以及怎么解决。博主小白非常欢迎大家的评论和帮助,万分感谢!

用代码改变世界!就是这样,喵!
原文地址:https://www.cnblogs.com/Song-Meow/p/12608909.html