查看: 121404|回复: 2591

[红客焦点]用纯C++实现位图的旋转

[复制链接]
发表于 2016-4-2 18:32:07 | 显示全部楼层 |阅读模式
本帖最后由 小圈圈 于 2016-4-2 18:51 编辑

目标:用纯C++将位图顺时针旋转90度
位图(Bitmap),顾名思义,就是用一个个像素点表示图片,每个像素点只有一种颜色,它的特点是放大后图像变成一个个色块
关于位图的科普文章大家可以看这篇http://www.cnblogs.com/lzlsky/archive/2012/08/16/2641698.html  挺全面的
要实现位图的旋转,就要改变像素的信息,大致分为以下几步
以二进制方式读取位图 ->按顺序获取位图的文件头和信息头 ->分配堆内存获取并存储像素信息->将原图中的每一个像素的信息写入旋转后图片的堆内存对应的位置->写入整个旋转后图片的信息
QQ图片20160402184052.png
QQ图片20160402184545.png
其中特别强调的是#pragma pack(1)这个预处理指令一定要有,它的功能是让编译器紧凑排列结构体中的内容,比如结构体中有char和int两种变量,正常来说char占1字节而int占4字节。而默认情况下编译器会给char类型分配4个字节的内存,这是为了和后面的int类型融合。加上#pragma pack(1)后就只给变量分配原来的内存了,我们接下来要按位读取数据,这个预处理指令,必须加!!
QQ图片20160402184649.png
接下来定义文件头和信息头,用fstream流读取图片,注意ifstream::read方法的第一个参数只能为char*类型,然而我们要读取其他类型的数据呢?不要管他,强制转换为char*即可,这个我试过了。
QQ图片20160402184741.png
为原图和旋转后的像素信息分配内存,将位图宽高交换后写入新的文件头,信息头
QQ图片20160402184848.png
上面还用到了一个补位函数fill0 ,因为微软规定位图像素信息每行的大小必须是4个字节的倍数,若不是需要用0补齐,我们获取需要补的字节数fill。
我们读取到行尾时跳过fill个字节,写入到行尾时写入fill个字节的0
然后进行位图的旋转,这里需要知道一点,就是位图的像素是按从下到上,从左到右的顺序存储的
比如像素是
A B  C D
E  F  G H
I   J  K  L
那么它在图片中写入的其实是IJKL EFGH ABCD
旋转后的像素为
I  E  A
J  F  B
K G  C
L H  D
在图片中写入的是LHD KGC JFB IEA
因此旋转图片的代码如下:
QQ图片20160402184935.png
最后写入新的像素数据,关闭流指针,别忘了删除new出来的堆内存
QQ图片20160402185019.png
然后大功告成了吗?事实上并没有 现在我们只能读取未压缩的图片,压缩后的图片由于信息头和像素数据之间有一段掩码信息,会导致图片损坏
这里有人会说读完信息头后跳过掩码信息,然而掩码信息的大小是不固定的,这怎么办?
细心地人可能注意到了上面有这段代码
QQ图片20160402185058.png
我们先读取信息头的大小biSize,然后将流指针返回信息头的初始位置,再读取信息头,读取的大小为biSize 之后发现流指针正好指向像素数据的开始位置
这说明biSize涵盖了原来信息头和后面的掩码信息大小,将掩码信息读入信息头并一并输出即可转换压缩后的图片
附效果图
QQ图片20160402183132.png
源代码 0402旋转位图.zip (2.48 KB, 下载次数: 4, 售价: 1 i币)
特别感谢:  error_
回复

使用道具 举报

发表于 2016-4-2 19:19:27 | 显示全部楼层
谢谢楼主的分享
回复 支持 反对

使用道具 举报

发表于 2016-4-2 20:48:09 | 显示全部楼层
回复 支持 反对

使用道具 举报

发表于 2016-4-2 21:45:03 | 显示全部楼层
我是来水经验的……
回复 支持 反对

使用道具 举报

发表于 2016-4-3 03:54:23 | 显示全部楼层
支持,看起来还是可以的
回复 支持 反对

使用道具 举报

发表于 2016-4-3 03:54:24 | 显示全部楼层
非常感谢
回复 支持 反对

使用道具 举报

发表于 2016-4-3 03:56:40 | 显示全部楼层
支持,看起来还是可以的
回复 支持 反对

使用道具 举报

发表于 2016-4-3 05:28:07 | 显示全部楼层
支持,看起来还是可以的
回复 支持 反对

使用道具 举报

发表于 2016-4-3 06:15:43 | 显示全部楼层
谢谢楼主的分享
回复 支持 反对

使用道具 举报

发表于 2016-4-3 06:36:18 | 显示全部楼层
支持,看起来还是可以的
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

指导单位

江苏省公安厅

江苏省通信管理局

浙江省台州刑侦支队

DEFCON GROUP 86025

旗下站点

邮箱系统

应急响应中心

红盟安全

联系我们

官方QQ群:112851260

官方邮箱:security#ihonker.org(#改成@)

官方核心成员

Archiver|手机版|小黑屋| ( 沪ICP备2021026908号 )

GMT+8, 2025-3-7 03:26 , Processed in 0.028834 second(s), 11 queries , Gzip On, MemCache On.

Powered by ihonker.com

Copyright © 2015-现在.

  • 返回顶部