“有没有内存小一点、模糊一点的图片?”(来自室友的提问)
“好像没什么用”系列第一篇博客文章
本文讨论的是我的关于如何缩减图片内存的简单又奇怪的想法
following are details.
一、启发
经常上学的朋友应该知道。 形式主义屡见不鲜(bushi),要不是为了点学分(确信) 就前两天,我室友(团支书)又要活动拍照,让我帮他拍了。
晚上他就发出了灵魂拷问(bushi),“有没有内存小一点的,就模糊一点内存小点的图片?” 看来是图片太大,达不到要求
我可没P图啊(真诚脸),那么问题来了,怎么样才能把这张原图弄模糊一点内存小一点呢?
二、突发奇想及实现
(一)想法
能不能把原图隔一个像素就取一个像素点,把这些像素点重新组成一张大约是原来1/4大小的生成图
(注意:为了做到等比例缩放,横竖都得是隔一取一)
(二)实现
1.具体步骤。
- 加载一张原图 img_src
- 生成一张空白生成图 img_gen
- 获取原图像素 buf_src
- 获取生成图像素 buf_gen
- 对原图像素隔一取一并赋值给生成图像素
- 保存生成图
2.操作实现
以下是上述步骤的C/C++实现,使用easyx图形库操作。
#include<stdio.h>
#include<stdlib.h>
#include<easyx.h>
int main(void)
{
//定义原图和结果图(生成图)
IMAGE image_source, image_result;
//用户输入
printf("input image path: ");
char path[256] = { 0 };
scanf("%s", path);
//加载原图
loadimage(&image_source, path);
//获取原图大小
int height = image_source.getheight();
int width = image_source.getwidth();
//根据原图大小创建对应的空白结果图
initgraph(width % 2 ? width / 2 + 1 : width / 2, height % 2 ? height / 2 + 1 : height / 2);
saveimage("生成图.jpg");
closegraph();
//加载结果图
loadimage(&image_result, "生成图.jpg");
//获取原图像素指针和结果图像素指针
DWORD* buff_source=GetImageBuffer(&image_source);
DWORD* buff_result = GetImageBuffer(&image_result);
//开始像素赋值,row和col分别表示原图像素行列
for (int row = 0; row < height; row += 2) //隔一行取一行
{
for (int col = 0; col < width; col += 2) //隔一个取一个
{
*buff_result = *(buff_source + row * width + col); //将原图像素点赋值到结果图对应位置
buff_result += 1; //结果图像素指针往后延伸
}
}
//保存结果图
saveimage("生成图.jpg", &image_result);
return 0;
}
(三)效果
原图一:
生成图一:
看起来似乎没有什么变化(可能是因为图片不够细节,看不出来什么),但实际上原图一分辨率为4200*3800
,所占内存大小为528kb
,而生成图一分辨率为2100*1900
,所占内存大小仅有157kb
。
原图二:
生成图二:
这两张图应该就相对明显一点了 (好像还是看不出来) (看不出来的可以用手机注意看煎蛋那个光泽),原图二分辨率为1920*1080
,所占内存大小为203kb
,生成图二分辨率为960*540
,所占内存大小仅有75.7kb
。
也许以上两个例子相对不太明显(第二个一定可以看出来),但是如果图片中有文字,比如上课拍摄的ppt图片等,可以较明显地看出模糊 by 文字变化。
好吧,那这一期就到这里结束了,下次再见。
It’s the end of the article.创作不易,转载请标明出处