引言
电脑里存了很多有意思的Gif动态图片,闲暇想把这些动图全导入微信表情,可是这些动图很多大小超过了微信表情大小1MB的限制,要制作成表情只能压缩图像文件大小。网上有很多小的图像处理软件和图像处理网站,尝试了很多,效果都并不是很好。于是决定自己动手来处理图像文件,让文件满足自己的要求。
动态Gif图像由很多静态图像组成,压缩方法无外乎有以下几种:
1、对每张图片进行裁剪,去掉无关紧要的背景。
2、每帧图像进行适当缩放。
3、每张图片降低色彩空间。
4、去除相似的静态图像,减少静态图像的数量。本想用PS来手动一帧一帧修改,无奈图片太多,实在太麻烦。最后想到了使用做图像处理最强大通用的工具Matlab来修改压缩图片。
先分享几张我压缩好制成微信表情的图片^ω^
以下定义一些变量:
gifname 需要处理的图像名称,完整路径;
cutname 处理之后的图像名称,完整路径;
cutregion 裁剪留下的方块区域;
scale 缩放比例;
cindex 颜色空间,可取2,4,8,16,32,64,128,256;
initframe 新图像第一帧对应源图像的帧数;
stepframe 新图像相邻两帧对应源图像帧序数之差;
stopframe 程序处理到源图像该帧数时停止;
delaytime 新图像两帧之间延迟时间
以下列出需要用到的重要函数:
Imfinfo() 该函数用于获取图片信息,包括图片的大小、格式、尺寸、颜色信息、修改时间等等。具体到Gif动图,它会获取到一个图片信息的结构体矩阵,可求出矩阵元素个数,即图片信息结构体的数量来获取Gif中存储的静态图片的数量。
具体用法:info=imfinfo(gifname);
Imread() 该函数用于读取图片文件中的数据。
具体用法:[indeximage,indexcolor]=imread(gifname,'frames',1);
imcrop() 该函数用于图像的裁剪。
具体用法:cutframe=imcrop(indeximage,indexcolor,cutregion);% cutregion=[1 1 100 100];
imresize() 该函数用于图像的缩放。
具体用法:[resframe,resindexcolor]=imresize(cutframe,indexcolor,scale,'bilinear');
ind2rgb() 索引颜色空间转换为rgb颜色空间
rgb2ind() rgb颜色空间转换为索引颜色空间
程序完整源代码如下:
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function[sourframes,destframes,usedframes]=gifcut(argin1,argin2,argin3,argin4) %输入参数[源文件名,目标文件名],裁剪区域[左上右下],缩放比例,[颜色索引,起始帧, 间隔帧,终止帧,延迟时间(最小0.01s)] %输出参数[源文件帧数,目标文件帧数,从源文件截取帧的编号] %此函数用于gif动态图裁剪,缩小,色彩降低,截取 %终止帧设为0时,读取到最后一帧;不输入延迟时间,默认延迟时间为原视频两帧间延迟, 延迟时间设为0时,输出gif两帧间延迟时间为原视频两帧间延迟*间隔帧数,延迟时间不 为0,输出gif两帧间延迟时间就是设置的延迟时间 %代码编写:theOwlAndPussyCat/焦旭光/2019.08.27 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% sourframes=0; destframes=0; usedframes=0; cutregion=[0000]; scale=1.0; cindex=256; initframe=1; stepframe=1; stopframe=1; if length(argin1)<1 error('There are not enough arguments') return else gifname=argin1(1); info=imfinfo(gifname); sourframes=length(info) delaytime=0.01*info(1).DelayTime; cindex=power(2,info(1).BitDepth); stopframe=sourframes; if length(argin1)<2 error('There are not enough arguments.') return end cutname=argin1(2); cutregion=argin2; scale=argin3; if length(argin4)>0 cindex=argin4(1); end if length(argin4)>1 initframe=argin4(2); end if length(argin4)>2 stepframe=argin4(3); end if length(argin4)>3 if argin4(4)==0 stopframe=stopframe; else stopframe=argin4(4); end end if length(argin4)>4 if argin4(5)==0 delaytime=0.01*delaytime*stepframe; else delaytime=argin4(5); end end end tempframe=1; for i=1:stopframe if i==initframe; [indeximage,indexcolor]=imread(gifname,'frames',i); cutframe=imcrop(indeximage,indexcolor,cutregion); if scale~=1.0 [resframe,resindexcolor]=imresize(cutframe,indexcolor,scale,'bilinear'); else resframe=cutframe; resindexcolor=indexcolor; end rgbframe=ind2rgb(resframe,resindexcolor); [recframe,recindexcolor]=rgb2ind(rgbframe,cindex); imwrite(recframe,recindexcolor,cutname,'gif','Loopcount',inf,'DelayTime',delaytime); tempframe=i; usedframes=tempframe; else if i==tempframe+stepframe && i>initframe [indeximage,indexcolor]=imread(gifname,'frames',i); cutframe=imcrop(indeximage,indexcolor,cutregion); if scale~=1.0 [resframe,resindexcolor]=imresize(cutframe,indexcolor,scale,'bilinear'); el
该matlab自定义函数使用方法:
将该函数保存为gifcut.m,文件夹下有testdog.gif文件,该文件大小为7.9MB,打开matlab调用此函数:
gifcut(["文件夹路径 estdog.gif","文件夹路径smalldog.gif"],[1,1,650,434],0.5,[8,2,2]);
用时176.077501 秒。生成文件smalldog.gif 大小为554KB。
gifcut(["文件夹路径 estdog.gif","文件夹路径smalldog2.gif"],[1,1,650,434],0.5,[8,2,3,0,0.2]);
用时118.895854 秒。掉帧略多。生成文件small_dog2.gif 大小为374KB。
范例文件如下: