一种残膜回收机防缠绕挑膜装置的制 一种秧草收获机用电力驱动行走机构

一种图像压缩方法、复原方法、计算设备及可读存储介质与流程

2023-01-06 02:30:08 来源:中国专利 TAG:


1.本发明涉及图像处理领域,尤其涉及一种图像压缩方法、复原方法、计算设备及可读存储介质。


背景技术:

2.图像的像素点越多,所占用的存储空间则越大,传输则越不方便。基于此,衍生出了各种图片格式(image format),如png、jpeg、webp等格式。然而,这些文件格式的压缩技术为了兼容每个图像的原始像素数据、保证数据的完整性,导致其压缩效果都不是很好。
3.为此,亟需一种新的图像压缩方法来解决上述技术问题。


技术实现要素:

4.为此,本发明提供了一种图像压缩方法、复原方法、计算设备及可读存储介质,以力图解决或者至少缓解上面存在的问题。
5.根据本发明的一个方面,提供一种图像压缩方法,包括:获取待压缩图像的数据文件,数据文件的像素缓冲区中包括各像素的透明度通道的透明度数据和若干个颜色通道的颜色数据;基于各像素的若干个颜色通道的颜色数据,检测待压缩图像是否为纯色图像;如果是:提取待压缩图像的纯色数据存储至预定位置;将各待压缩像素的透明度数据转换为单通道图像的颜色数据,待压缩像素为透明度数据不为0的像素,纯色数据为待压缩像素全部颜色通道的颜色数据;删除像素缓冲区中各像素的透明度数据和若干个颜色通道的颜色数据,并将像素缓冲区的大小缩小至单通道宽度;将各待压缩像素的透明度数据所转换成的颜色数据写入对应的像素缓冲区中,得到压缩图像。
6.可选地,在根据本发明的图像压缩方法中,检测待压缩图像是否为纯色图像,包括:检测所有像素的同一颜色通道的颜色数据是否相同;或者检测所有待压缩像素的同一颜色通道的颜色数据是否相同。
7.可选地,在根据本发明的图像压缩方法中,将各待压缩像素的透明度数据转换为单通道图像的颜色数据,包括:将各待压缩像素的透明度数据作为单通道图像的颜色数据。
8.可选地,在根据本发明的图像压缩方法中,单通道图像为灰度图像,相应地,单通道图像的颜色数据为灰度图像的亮度。
9.可选地,在根据本发明的图像压缩方法中,预定位置为数据文件中的预定字段,或数据文件的文件名中的预定字段,或打开压缩图像的应用程序的内部缓冲。
10.可选地,在根据本发明的图像压缩方法中,待压缩图像为图标图像。
11.可选地,在根据本发明的图像压缩方法中,若干个颜色通道包括红色通道、绿色通道和蓝色通道。
12.根据本发明的又一个方面,提供一种复原由上述方法得到的压缩图像的方法,包括:基于预定位置中存储的纯色数据,构造压缩图像压缩前各像素的各颜色通道的颜色数据;基于压缩图像的数据文件的像素缓冲区中各像素的颜色通道的颜色数据,构造压缩图
像压缩前各像素的透明度通道的透明度数据;基于所构造的各像素的透明度通道的透明度数据及各颜色通道的颜色数据,对压缩图像进行复原。
13.可选地,在根据本发明的复原方法中,对压缩图像进行复原,包括:将像素缓冲区中各像素的颜色数据删除;将像素缓冲区大小扩展为压缩前的大小,并将所构造的各像素的透明度通道的透明度数据及各颜色通道的颜色数据写入像素缓冲区中;将预定位置中存储的纯色数据删除。
14.可选地,在根据本发明的复原方法中,对压缩图像进行复原,包括:根据所构造的各像素的透明度通道的透明度数据及各颜色通道的颜色数据,利用绘制系统将各像素渲染至打开压缩图像的应用程序的界面中。
15.可选地,在根据本发明的复原方法中,预定位置为数据文件中的预定字段,或数据文件的文件名中的预定字段,或打开压缩图像的应用程序的内部缓冲。
16.可选地,在根据本发明的复原方法中,压缩图像压缩前各像素的各颜色通道包括红色通道、绿色通道和蓝色通道。
17.根据本发明的又一个方面,提供一种计算设备,包括:至少一个处理器;以及存储器,存储有程序指令,其中,程序指令被配置为适于由至少一个处理器执行,程序指令包括用于执行如上方法中的任一方法的指令。
18.根据本发明的又一个方面,提供一种存储有程序指令的可读存储介质,当程序指令被计算设备读取并执行时,使得计算设备执行如上方法中的任一方法。
19.本发明针对纯色图像提供了一种单一颜色通道的图像压缩方法,该方法可以在不改变原始图像格式的条件下,大幅提高图像的压缩率。并且,本发明还提供了相应的图像复原方法,其能对使用上述单一颜色通道的图像压缩方法压缩得到的图像进行无损复原。
附图说明
20.为了实现上述以及相关目的,本文结合下面的描述和附图来描述某些说明性方面,这些方面指示了可以实践本文所公开的原理的各种方式,并且所有方面及其等效方面旨在落入所要求保护的主题的范围内。通过结合附图阅读下面的详细描述,本公开的上述以及其它目的、特征和优势将变得更加明显。遍及本公开,相同的附图标记通常指代相同的部件或元素。
21.图1示出了根据本发明一个实施例的计算设备100的结构框图;图2示出了根据本发明一个实施例的图像压缩方法200的流程图;图3示出了根据本发明一个实施例的像素点的像素数据结构分布的示意图;图4示出了根据本发明一个实施例的像素点的转换后的像素数据结构分布的示意图;图5示出了根据本发明一个实施例的向png文件中写入数据的流程图的示意图;图6示出了根据本发明又一个实施例的图像压缩方法的流程图的示意图;图7示出了根据本发明一个实施例的图像复原方法700的流程图;图8示出了根据本发明一个实施例的文件层复原图像的方法的流程图的示意图;图9示出了根据本发明一个实施例的图像复原过程的示意图。
具体实施方式
22.下面将参照附图更详细地描述本公开的示例性实施例。虽然附图中显示了本公开的示例性实施例,然而应当理解,可以以各种形式实现本公开而不应被这里阐述的实施例所限制。相反,提供这些实施例是为了能够更透彻地理解本公开,并且能够将本公开的范围完整的传达给本领域的技术人员。
23.目前的png、jpeg、webp等格式的压缩技术,其压缩效果都不是很好。例如,以png格式为例,下表1示出了一个纯色图标包含不同数量的像素点时,其原始文件的大小和png文件的大小:表1可见,当纯色图标的大小增大时,png文件的大小也会随之增大。显然,如果计算机中存储的图标都如上述展示的大小,则应用程序所需的资源文件将占应用程序的很大一部分且不可分割,对系统资源将造成很大的浪费。基于此,本发明提出了一种针对纯色图像的单一颜色通道的图像压缩方法和对应的图像复原方法,该方法能大幅提高图像的压缩率,并且可实现无损复原。
24.图1示出了计算设备100的物理组件(即,硬件)的框图。在基本配置中,计算设备100包括至少一个处理单元102和系统存储器104。根据一个方面,取决于计算设备的配置和类型,处理单元102可以实现为处理器。系统存储器104包括但不限于易失性存储(例如,随机存取存储器)、非易失性存储(例如,只读存储器)、闪速存储器、或者这样的存储器的任何组合。根据一个方面,系统存储器104中包括操作系统105和程序模块106,程序模块106中包括图像压缩模块120和图像复原模块130,图像压缩模块120被配置为执行本发明的图像压缩方法200,图像复原模块130被配置为执行本发明的图像复原方法700。
25.根据一个方面,操作系统105例如适合于控制计算设备100的操作。此外,示例结合图形库、其他操作系统、或任何其他应用程序而被实践,并且不限于任何特定的应用或系统。在图1中通过在虚线108内的那些组件示出了该基本配置。根据一个方面,计算设备100具有额外的特征或功能。例如,根据一个方面,计算设备100包括额外的数据存储设备(可移动的和/或不可移动的),例如磁盘、光盘、或者磁带。这样额外的存储在图1中是由可移动存储109和不可移动存储110示出的。
26.如在上文中所陈述的,根据一个方面,在系统存储器104中存储有程序模块。根据一个方面,程序模块可以包括一个或多个应用程序,本发明不限制应用程序的类型,例如应用程序可以包括:电子邮件和联系人应用程序、文字处理应用程序、电子表格应用程序、数据库应用程序、幻灯片展示应用程序、绘画或计算机辅助应用程序、网络浏览器应用程序等。
27.根据一个方面,可以在包括分立电子元件的电路、包含逻辑门的封装或集成的电子芯片、利用微处理器的电路、或者在包含电子元件或微处理器的单个芯片上实践示例。例如,可以经由其中在图1中所示出的每个或许多组件可以集成在单个集成电路上的片上系统(soc)来实践示例。根据一个方面,这样的soc设备可以包括一个或多个处理单元、图形单元、通信单元、系统虚拟化单元、以及各种应用功能,其全部作为单个集成电路而被集成(或“烧”)到芯片基底上。当经由soc进行操作时,可以经由在单个集成电路(芯片)上与计算设备100的其他组件集成的专用逻辑来对在本文中所描述的功能进行操作。还可以使用能够执行逻辑操作(例如and、or和not)的其他技术来实践本发明的实施例,所述其他技术包括但不限于机械、光学、流体、和量子技术。另外,可以在通用计算机内或在任何其他任何电路或系统中实践本发明的实施例。
28.根据一个方面,计算设备100还可以具有一个或多个输入设备112,例如键盘、鼠标、笔、语音输入设备、触摸输入设备等。还可以包括输出设备114,例如显示器、扬声器、打印机等。前述设备是示例并且也可以使用其他设备。计算设备100可以包括允许与其他计算设备118进行通信的一个或多个通信连接116。合适的通信连接116的示例包括但不限于:rf发射机、接收机和/或收发机电路;通用串行总线(usb)、并行和/或串行端口。
29.如在本文中所使用的术语计算机可读介质包括计算机存储介质。计算机存储介质可以包括以任何用于存储信息(例如,计算机可读指示、数据结构、或程序模块)的方法或技术来实现的易失性的和非易失性的、可移动的和不可移动的介质。系统存储器104、可移动存储109、和不可移动存储110都是计算机存储介质的示例(即,存储器存储)。计算机存储介质可以包括随机存取存储器(ram) 、只读存储器(rom) 、电可擦只读存储器(eeprom)、闪速存储器或其他存储器技术、cd-rom、数字通用盘(dvd)或其他光存储、盒式磁带、磁带、磁盘存储器或其他磁存储设备、或者可用于存储信息并且可以由计算设备100访问的任何其他制品。根据一个方面,任何这样的计算机存储介质都可以是计算设备100的一部分。计算机存储介质不包括载波或其他经传播的数据信号。
30.根据一个方面,通信介质是由计算机可读指令、数据结构、程序模块、或者经调制的数据信号(例如,载波或其他传输机制)中的其他数据实施的,并且包括任何信息传递介质。根据一个方面,术语“经调制的数据信号”描述了具有一个或多个特征集或者以将信息编码在信号中的方式改变的信号。作为示例而非限制,通信介质包括诸如有线网络或直接有线连接之类的有线介质,以及诸如声学、射频(rf)、红外线的、以及其他无线介质之类的无线介质。
31.图2示出了根据本发明一个实施例的图像压缩方法200的流程图,方法200适于在计算设备(例如图1所示的计算设备100)中执行。如图2所示,该方法200始于210。
32.在210中,获取待压缩图像的数据文件,数据文件的像素缓冲区中包括各像素的透明度通道的透明度数据和若干个颜色通道的颜色数据。即,本实施例中的待压缩图像中的每个像素由透明度通道和若干个颜色通道组成(也就是说待压缩图像为多通道图像,其像素由多个通道组成)。其中,在一些实施例中,若干个颜色通道具体可以包括红色通道、绿色通道和蓝色通道,即待压缩图像中的每个像素由透明度(a)、红(r)、绿(g)和蓝(b)四个通道组成(换句话说,待压缩图像为argb颜色模式的图像)。
33.a、r、g、b每个通道由8bit大小的数据存储,因此可以用unsigned char表示a、r、g、
b各个通道的数据。由于a、r、g、b每个通道都由8bit大小的数据存储,因此每个像素点所占用的大小为32bit(4
×
8=32),和计算设备中的unsigned int类型具有相同的字节数量,因此可以用unsigned int类型表示每个像素点的值,如图3,其示出了一个像素点的像素数据(或者说像素值)的结构分布。
34.根据本发明的一个实施例,图3所示出的像素数据的结构分布的示例性代码如下:typedef unsigned int pixeldata;typedef unsigned char channeldata;static channeldata redchannel(pixeldata pixel){
ꢀꢀꢀꢀ
return ((pixel 》》 16) & 0xff);}static channeldata greenchannel(pixeldata pixel){
ꢀꢀꢀꢀ
return ((pixel 》》 8) & 0xff);}static channeldata bluechannel(pixeldata pixel){
ꢀꢀꢀꢀ
return (pixel & 0xff);}static channeldata alphachannel(pixeldata pixel){
ꢀꢀꢀꢀ
return (pixel 》》 24);}static pixeldata makepixel(channeldata r, channeldata g, channeldata b, channeldata a){
ꢀꢀꢀꢀ
return ((a & 0xffu) 《《 24) | ((r & 0xffu) 《《 16) | ((g & 0xffu) 《《 8) | (b & 0xffu);}static pixeldata convertpixelargbtorgb(pixeldata argb){
ꢀꢀꢀꢀ
if (alphachannel(argb) == 0)
ꢀꢀꢀꢀꢀꢀꢀꢀ
return argb;
ꢀꢀꢀꢀ
return makepixel(redchannel(argb), greenchannel(argb), bluechannel(argb), 0);}其中,一些图片格式(如png)在不同的大小端机器上进行的数据字节写入方式不同,大端机器使用argb存储,小端使用bgra存储,相应地,数据读取则可使用argb或bgra。具体地,在本实施例中,可以使用argb进行数据读取。
35.下面作一示例,待压缩图像为png格式,则通过png动态库所提供的读取接口,按照argb形式获取待压缩图像的数据文件,示例性代码如下:bool pnghander::readpngheader(png_struct *png_ptr, png_info *info_ptr){
ꢀꢀꢀꢀ
png_get_ihdr(png_ptr, info_ptr, &data-》width, &data-》height, &data-》depth, &data-》color_type, nullptr, nullptr, nullptr);
ꢀꢀꢀꢀ
data-》bytes_per_line = png_get_rowbytes(png_ptr, info_ptr);
ꢀꢀꢀꢀ
data-》bytes = new channeldata [data-》height * data-》bytes_per_line];
ꢀꢀꢀꢀ
data-》nbytes = data-》bytes_per_line * data-》height;
ꢀꢀꢀꢀ
png_set_bgr(png_ptr);
ꢀꢀꢀꢀ
return true;}bool pnghander::readpngdata(std::string src_file_name){
ꢀꢀꢀꢀ
png_struct* png_ptr;
ꢀꢀꢀꢀ
png_info *info_ptr;
ꢀꢀꢀꢀ
if (!(png_ptr = png_create_read_struct(png_libpng_ver_string, nullptr, nullptr, nullptr)))
ꢀꢀꢀꢀꢀꢀꢀꢀ
return false;
ꢀꢀꢀꢀ
if (!(info_ptr = png_create_info_struct(png_ptr))) {
ꢀꢀꢀꢀꢀꢀꢀꢀ
png_destroy_read_struct(&png_ptr, nullptr, nullptr);
ꢀꢀꢀꢀꢀꢀꢀꢀ
png_ptr = nullptr;
ꢀꢀꢀꢀꢀꢀꢀꢀ
return false;
ꢀꢀꢀꢀ
}
ꢀꢀꢀꢀ
if (setjmp(png_jmpbuf(png_ptr))) {
ꢀꢀꢀꢀꢀꢀꢀꢀ
png_destroy_read_struct(&png_ptr, nullptr, nullptr);
ꢀꢀꢀꢀꢀꢀꢀꢀ
png_ptr = nullptr;
ꢀꢀꢀꢀꢀꢀꢀꢀ
return false;
ꢀꢀꢀꢀ
}
ꢀꢀꢀꢀ
std::ifstream file;
ꢀꢀꢀꢀ
file.open(src_file_name, std::ios::in);
ꢀꢀꢀꢀ
if (!file.is_open())
ꢀꢀꢀꢀꢀꢀꢀꢀ
return false;
ꢀꢀꢀꢀ
png_set_read_fn(png_ptr, (png_voidp)&file, read_png_fn);
ꢀꢀꢀꢀ
png_set_keep_unknown_chunks(png_ptr, png_handle_chunk_always, const_cast《png_bytep》((const png_byte *)rgbsig_name), 1);
ꢀꢀꢀꢀ
png_set_read_user_chunk_fn(png_ptr, &data-》color_sig, read_color_
sig_chunk);
ꢀꢀꢀꢀ
png_read_info(png_ptr, info_ptr);
ꢀꢀꢀꢀ
if (!readpngheader(png_ptr, info_ptr))
ꢀꢀꢀꢀꢀꢀꢀꢀ
return false;
ꢀꢀꢀꢀ
png_bytepp buffer = (png_bytepp)png_malloc(png_ptr, data-》height * sizeof (png_bytepp));
ꢀꢀꢀꢀ
for (pixeldata i = 0; i 《 data-》height; i)
ꢀꢀꢀꢀꢀꢀꢀꢀ
buffer[i] = data-》bytes i * data-》bytes_per_line;
ꢀꢀꢀꢀ
png_read_image(png_ptr, buffer);
ꢀꢀꢀꢀ
png_free(png_ptr, buffer);
ꢀꢀꢀꢀ
png_destroy_read_struct(&png_ptr, &info_ptr, nullptr);
ꢀꢀꢀꢀ
png_ptr = nullptr;
ꢀꢀꢀꢀ
info_ptr = nullptr;
ꢀꢀꢀꢀ
file.close();
ꢀꢀꢀꢀ
return true;}//将待压缩图像的各数据读取到该类中的data结构体中,该结构体的数据成员展示如下: struct pngdata {
ꢀꢀꢀꢀ
png_uint_32 width;
ꢀꢀꢀꢀ
png_uint_32 height;
ꢀꢀꢀꢀ
int depth;
ꢀꢀꢀꢀ
int color_type;
ꢀꢀꢀꢀ
unsigned long bytes_per_line;
ꢀꢀꢀꢀ
unsigned long nbytes;
ꢀꢀꢀꢀ
pixeldata color_sig;
ꢀꢀꢀꢀ
channeldata *bytes = nullptr;} *data;可见,在本实施例中,待压缩图像的数据文件中除包括各像素的红、绿、蓝和透明度四个通道的数据之外,还包括待压缩图像的大小width和height(即像素点的数量);色彩深度depth,通常情况下png仅存在1和8的色彩深度,如argb、rgb、gray(灰度图)深度为8,其他类型像素深度为1,该深度主要用于png的内部解析和编码;图像的类型color_type;每行的像素字节大小bytes_per_line,其表示的是每行数据中的像素通道的大小,通常情况下该像素通道大小等于width
×
通道字节数,但由于存在宽度为单数的情况,因此有些算法下该大小等于((width
×
通道字节数 31)/32)
×
4;图像数值所有的字节数量nbytes;提取出的纯色数据color,即剔除alpha后的rgb值;以及所有的图像通道字节数量bytes。
[0036]
需说明的是,上述所示出的各颜色通道为红色、绿色和蓝色通道,只是一个示例,对于各颜色通道,本发明不作限定。另外,对于待压缩图像本发明也不作限定,例如其可以为图标图像。
[0037]
至此,便获得了待压缩图像的数据文件,随后进入220,基于各像素的若干个颜色通道的颜色数据,检测待压缩图像是否为纯色图像。
[0038]
根据本发明的一个实施例,可以通过检测所有像素的同一颜色通道的颜色数据是否相同,来判定待压缩图像是否为纯色图像。即,对于除透明度通道之外的每一个颜色通道,检测所有像素的该颜色通道的颜色数据是否相同,如果全部相同,则判定待压缩图像为纯色图像,否则判定待压缩图像为非纯色图像。
[0039]
另外,在一些实施例中,考虑到透明度数据为0的像素,无论其颜色通道的颜色数据具体为何值,该像素最终的显示效果都为纯透明,因此,为了减少检测的数据量、缩短检测时间,在判断待压缩图像是否为纯色图像时,还可以只对透明度数据不为0的像素的同一颜色通道的颜色数据是否相同进行检测,如果透明度不为0的像素的同一颜色通道的颜色数据均相同,则判定待压缩图像为纯色图像,否则判定其为非纯色图像。
[0040]
如果待压缩图像为纯色图像,则进入230,提取待压缩图像的纯色数据存储至预定位置。即,提取待压缩图像的纯色数据,并将其存储至预定位置。
[0041]
在此先对纯色数据进行一下说明。在纯色图像中,所有像素使用相同的颜色数据(上述已指出纯色图像中所有像素的同一颜色通道的颜色数据一致),该共用颜色数据则为纯色图像的纯色数据。因此,待压缩图像的纯色数据即为待压缩图像中所有像素的共用颜色数据,进一步讲,待压缩图像的纯色数据即为待压缩图像中任一像素的全部颜色通道的颜色数据。基于此,提取待压缩图像的纯色数据,具体可以为,提取任一像素的除透明度通道之外的所有颜色通道的颜色数据(提取到的所有颜色通道的颜色数据即为待压缩图像的纯色数据)。例如颜色通道为r、g、b时(即待压缩图像有a、r、g和b四个通道),待压缩图像中所有像素的rgb字段数据都为一个相同的固定数值,进一步讲,各像素的rgb字段所组成的24位的数值均相同,则将该数值提取出来作为待压缩图像的纯色数据。
[0042]
其中,预定位置可以为待压缩图像的数据文件中自定义的一个预定字段,也可以为待压缩图像的数据文件的文件名中自定义的一个预定字段,还可以为打开待压缩图像的应用程序的内部缓冲。即,将提取到的纯色数据存储至预定位置时,可以将提取到的纯色数据存储至数据文件的预定字段中,或者将提取到的纯色数据存储至数据文件的文件名的预定字段中,或者将提取到的纯色数据存储至打开待压缩图像的应用程序的内部缓冲中。关于具体以上述哪种方式来存储所提取到的纯色数据,本发明不作限定,在具体的实施例中,本领域的技术人可以根据实际需要进行设定。
[0043]
在提取出待压缩图像的纯色数据并进行存储后,可将像素缓冲区中透明度不为0的像素的各颜色通道的颜色数据均修改(或者说转换)为0,这样便能将待压缩图像中透明度不为0的像素点的像素数据从n个字节的大小减少为1个字节大小的alpha数据和n-1个字节的“0”数据。对于透明度为0的像素点,考虑到其显示效果为纯透明,则可直接删除。
[0044]
下面继续以各颜色通道为r、g、b为例作一示例,具体地,在确定待压缩图像为纯色图像后,将待压缩图像中透明度为0的像素点的a、r、g、b通道的数据删除,提取待压缩图像的统一rgb值,并将透明度不为0的像素的r、g、b通道的颜色数据转换为0,这样便能将待压缩图像中透明度不为0的像素点的像素数据从4个字节的大小减少为1个字节大小的alpha数据和3个字节的“0”数据,转换后的像素数据分布可见图4。
[0045]
其中,上述示例中判断待压缩图像是否为纯色图像,遍历待压缩图像的所有像素
数据,删除透明度为0的像素点,提取待压缩图像的统一rgb值,以及将透明度不为0的像素点的rgb数据转换为0的示例性代码如下:bool pnghander::canextractrgb(){
ꢀꢀꢀꢀ
if (!data)
ꢀꢀꢀꢀꢀꢀꢀꢀ
return false;
ꢀꢀꢀꢀ
// not supported for rgb or rgba.
ꢀꢀꢀꢀ
if ((data-》color_type != png_color_type_rgba)
ꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀ
&& (data-》color_type != png_color_type_rgb)) {
ꢀꢀꢀꢀꢀꢀꢀꢀ
return false;
ꢀꢀꢀꢀ
}
ꢀꢀꢀꢀ
if (!data-》bytes)
ꢀꢀꢀꢀꢀꢀꢀꢀ
return false;
ꢀꢀꢀꢀ
return true;}long pnghander::extractrgb(){
ꢀꢀꢀꢀ
if (!canextractrgb())
ꢀꢀꢀꢀꢀꢀꢀꢀ
return
ꢀ‑
1;
ꢀꢀꢀꢀ
static pixeldata pp = 0;
ꢀꢀꢀꢀ
pixeldata *pixels = (pixeldata *)data-》bytes;
ꢀꢀꢀꢀ
bool extracted = std::all_of(pixels, pixels data-》nbytes / sizeof (pixeldata), [](pixeldata data)
ꢀ‑
》 bool {
ꢀꢀꢀꢀꢀꢀꢀꢀ
pixeldata rgb = convertpixelargbtorgb(data);
ꢀꢀꢀꢀꢀꢀꢀꢀ
if (pp == 0) {
ꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀ
pp = rgb;
ꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀ
return true;
ꢀꢀꢀꢀꢀꢀꢀꢀ
}
ꢀꢀꢀꢀꢀꢀꢀꢀ
return (data == 0) || (pp == rgb);
ꢀꢀꢀꢀ
});
ꢀꢀꢀꢀ
if (extracted)
ꢀꢀꢀꢀꢀꢀꢀꢀ
return pp;
ꢀꢀꢀꢀ
return
ꢀ‑
1;
ꢀꢀ
// can't be extract.}至此可见,上述示出了可通过将待压缩图像中透明度为0的像素点删除、将透明度不为0的像素点的各颜色通道的数据转换为0,来对待压缩图像进行压缩,从而减少待压缩图像所占用的空间。然而,“0”数据仍会占用内存,因此在一些实施例中,为了进一步减少待压缩图像压缩后所占用的空间,可通过将多个字节的数据重新整理为一个字节的数据并写入到图像中的方式,来完成压缩数据的写入,从而实现对待压缩图像的压缩。例如,待压缩
图像为argb颜色模式的图像时,可将像素的四个字节的数据重新整理为一个字节数据并写入到图像中来对待压缩图像进行压缩。下面通过240来对如何将待压缩图像中像素的多个字节的数据重新整理为一个字节的数据进行说明,具体如下。
[0046]
在240中,将各待压缩像素的透明度数据转换为单通道图像的颜色数据。为了便于表述,本实施例将透明度不为0的像素称为待压缩像素。
[0047]
由于透明度为0的像素点显示为纯透明,因此在本实施例中也可将透明度为0的像素直接删除,只对透明度不为0的像素进行多字节转一字节的处理,即只对待压缩像素进行多字节转一字节的处理。具体地,上述在判定待压缩图像为纯色图像时,已提取出待压缩图像的纯色数据,因此对于各待压缩像素,只需再存储其透明度数据,则可知晓其各通道的数据(即像素数据)。基于此,在将各待压缩像素的多个字节重新整理为一个字节时,可将其颜色通道的颜色数据删除,只对透明度数据进行转换以记录透明度数据。而考虑到单通道图像只有一个颜色通道,因此可在对各待压缩像素进行多字节转一字节的处理时,将其透明度数据转换为单通道图像的颜色数据,即将透明度数据转换为单通道图像所具有的那个唯一颜色通道的颜色数据。进一步地,在一些实施例中,在将各待压缩像素的透明度数据转换为单通道图像所具有的唯一颜色通道的颜色数据时,可直接将透明度数据作为单通道图像的该颜色数据。当然,这只是一个示例,对此本发明不作限定。
[0048]
其中,灰度(grayscale-8bit)图像的存储模式为8位存储,其数据在0~255之间变化,用于保存灰色的亮度。因此,灰度图像并不存在argb的像素数据,其只有像素亮度一种。基于此,在一些实施例中,单通道图像可以为灰度图像,相应地,单通道图像的颜色数据则为灰度图像的亮度,即在对各待压缩像素进行多字节转一字节的处理时,将不透明度数据转化为灰度图像的亮度从而将待压缩图像储存为灰度图像,这种操作既不会损失字节数据,又能减少文件存储大小。
[0049]
需说明的是,在将各待压缩像素的透明度数据转化为灰色通道的亮度时,需适应gray(灰度)格式的数据,以便后续在数据写入时能匹配到正确图片深度的像素点。
[0050]
至此,便将各待压缩像素的透明度数据转换成了单通道图像的颜色数据,随后进入250,删除像素缓冲区中各像素的透明度数据和若干个颜色通道的颜色数据,并将像素缓冲区的大小缩小至单通道宽度。即,将待压缩图像的像素缓冲区中的各像素的像素数据(即透明度数据和各颜色通道的颜色数据)删除,并将待压缩图像的像素缓冲区的大小从多通道宽度缩小至单通道宽度。例如,当待压缩图像为argb颜色模式的图像且单通道图像为灰度图像时,则将待压缩像素的像素缓冲区的大小缩小为其1/4。
[0051]
随后进入260,将各待压缩像素的透明度数据所转换成的颜色数据写入对应的像素缓冲区中,得到压缩图像。即,将每一个待压缩像素的透明度数据所转换成的单通道图像所具有的那个唯一通道的数据,写入该像素所对应的像素缓冲区中,从而得到待压缩图像压缩后的压缩图像。例如,当单通道图像为灰度图像时,则可将每个待压缩像素的透明度数据作为其灰色通道的亮度数据填充至该像素所对应的像素缓冲区中。
[0052]
为了更好的理解写入过程,下面以待压缩图像的颜色模式为argb、格式为png,单通道图像为灰度图像,以及预定位置为待压缩图像的数据文件中的预定字段为例作一示例,具体可参见图5。首先,对各待压缩像素的像素数据(即原始数据)进行图像深度的适配处理,将像素数据转换成适应灰度(gray)格式的数据,图像深度由32位缩减到8位,然后使
用png提供的标准图像写入接口将各待压缩像素的透明度数据作为灰度图像的亮度写入png数据文件中,并将所提取到的待压缩图像的共用rgb数据存储至png数据文件的预定字段中,从而完成数据的写入。
[0053]
根据本发明的一个实施例,通过png提供的标准图像写入接口将待压缩图像压缩后的各数据写入数据文件的示例性代码如下:// 删除图像中rgb数据void pnghander::removergbcolordata(){
ꢀꢀꢀꢀ
// 重新计算数据量大小
ꢀꢀꢀꢀ
data-》nbytes /= sizeof(pixeldata);
ꢀꢀꢀꢀ
channeldata *buffer = new channeldata[data-》nbytes];
ꢀꢀꢀꢀ
pixeldata *pixels = (pixeldata *)data-》bytes;
ꢀꢀꢀꢀ
channeldata *dest = buffer;
ꢀꢀꢀꢀ
for (pixeldata *p = pixels; p 《 pixels (data-》nbytes); p, dest)
ꢀꢀꢀꢀꢀꢀꢀꢀ
*dest = alphachannel(*p);
ꢀꢀ
// 压缩数据使用源数据中alpha值填充
ꢀꢀꢀꢀ
delete[] data-》bytes;
ꢀꢀꢀꢀ
data-》bytes = buffer;
ꢀꢀꢀꢀ
data-》bytes_per_line /= sizeof(pixeldata);
ꢀꢀ
// 更新属性信息}bool pnghander::writepngdata(const std::string &out_file_name, int out_ct, int quality, pixeldata rgb){
ꢀꢀꢀꢀ
png_struct* png_ptr;
ꢀꢀꢀꢀ
png_info *info_ptr;
ꢀꢀꢀꢀ
png_ptr = png_create_write_struct(png_libpng_ver_string, nullptr, nullptr, nullptr);
ꢀꢀ
//
ꢀꢀ
创建png数据块
ꢀꢀꢀꢀ
if (!png_ptr)
ꢀꢀꢀꢀꢀꢀꢀꢀ
return false;
ꢀꢀꢀꢀ
info_ptr = png_create_info_struct(png_ptr);
ꢀꢀ
// 创建png信息块
ꢀꢀꢀꢀ
if (!info_ptr) {
ꢀꢀꢀꢀꢀꢀꢀꢀ
png_destroy_write_struct(&png_ptr, nullptr);
ꢀꢀꢀꢀꢀꢀꢀꢀ
return false;
ꢀꢀꢀꢀ
}
ꢀꢀꢀꢀ
if (setjmp(png_jmpbuf(png_ptr))) {
ꢀꢀ
// 多线程操作保护
ꢀꢀꢀꢀꢀꢀꢀꢀ
png_destroy_write_struct(&png_ptr, &info_ptr);
ꢀꢀꢀꢀꢀꢀꢀꢀ
return false;
ꢀꢀꢀꢀ
}
ꢀꢀꢀꢀ
std::ofstream file;
ꢀꢀ
// 输出文件流
ꢀꢀꢀꢀ
file.open(out_file_name, std::ios::out | std::ios::trunc | std::ios::binary);
ꢀꢀ
// 二进制方式写入
ꢀꢀꢀꢀ
if (!file.is_open())
ꢀꢀꢀꢀꢀꢀꢀꢀ
return false;
ꢀꢀꢀꢀ
// 设置写入的io回调函数
ꢀꢀꢀꢀ
png_set_write_fn(png_ptr, (png_voidp)&file, write_png_fn, write_flush_fn);
ꢀꢀꢀꢀ
// 设置png头信息png_set_ihdr(png_ptr, info_ptr, data-》width, data-》height, data-》depth, out_ct, 0, 0, 0);
ꢀꢀꢀꢀ
// 小端用bgra存储 因此需要转换
ꢀꢀꢀꢀ
png_set_bgr(png_ptr);
ꢀꢀ
// big endian: argb little endian bgra.
ꢀꢀꢀꢀ
if (rgb != 0) {
ꢀꢀꢀꢀꢀꢀꢀꢀ
uchar color_sig[3];
ꢀꢀꢀꢀꢀꢀꢀꢀ
color_sig[0] = redchannel(rgb);
ꢀꢀꢀꢀꢀꢀꢀꢀ
color_sig[1] = greenchannel(rgb);
ꢀꢀꢀꢀꢀꢀꢀꢀ
color_sig[2] = bluechannel(rgb);
ꢀꢀꢀꢀꢀꢀꢀꢀ
png_unknown_chunk color_chunk = {
ꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀ
rgbsig_name,
ꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀ
color_sig,
ꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀ
sizeof (color_sig),
ꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀ
png_have_ihdr
ꢀꢀꢀꢀꢀꢀꢀꢀ
};
ꢀꢀꢀꢀꢀꢀꢀꢀ
// 写入rgb数据块到自定义数据中
ꢀꢀꢀꢀꢀꢀꢀꢀ
png_set_unknown_chunks(png_ptr, info_ptr, &color_chunk, 1);
ꢀꢀꢀꢀ
}
ꢀꢀꢀꢀ
// 写入信息 其中包含头部信息和自定义数据块信息
ꢀꢀꢀꢀ
png_write_info(png_ptr, info_ptr);
ꢀꢀꢀꢀ
png_set_packing(png_ptr);
ꢀꢀꢀꢀ
// 设置压缩级别 从0-9取值,0为不压缩
ꢀꢀꢀꢀ
png_set_compression_level(png_ptr, quality);
ꢀꢀꢀꢀ
png_bytepp buffer = (png_bytepp)png_malloc(png_ptr, data-》height * sizeof (png_bytepp));
ꢀꢀꢀꢀ
for (int y = 0; y 《 data-》height; y )
ꢀꢀꢀꢀꢀꢀꢀꢀ
buffer[y] = data-》bytes y * data-》bytes_per_line;
ꢀꢀꢀꢀ
// 写入图片数据
ꢀꢀꢀꢀ
png_write_image(png_ptr, buffer);
ꢀꢀꢀꢀ
png_free(png_ptr, buffer);
ꢀꢀꢀꢀ
png_write_end(png_ptr, info_ptr);
ꢀꢀꢀꢀ
png_destroy_write_struct(&png_ptr, &info_ptr);
ꢀꢀꢀꢀ
file.close();
ꢀꢀꢀꢀ
return true;}static void write_png_fn(png_structp png_ptr, png_bytep data, png_size_t length){
ꢀꢀꢀꢀ
std::ofstream *ofs = (std::ofstream *)png_get_io_ptr(png_ptr);
ꢀꢀꢀꢀ
if (!ofs || !ofs-》is_open())
ꢀꢀꢀꢀꢀꢀꢀꢀ
return;
ꢀꢀꢀꢀ
// 写回调直接操作ofstream进行写入
ꢀꢀꢀꢀ
ofs-》write((char*)data, length);}static void write_flush_fn(png_structp png_ptr){
ꢀꢀꢀꢀ
std::ofstream *ofs = (std::ofstream *)png_get_io_ptr(png_ptr);
ꢀꢀꢀꢀ
if (!ofs || !ofs-》is_open())
ꢀꢀꢀꢀꢀꢀꢀꢀ
return;
ꢀꢀꢀꢀ
// 写刷新直接刷新
ꢀꢀꢀꢀ
ofs-》flush();}至此,便将各待压缩像素的透明度数据所转换成的颜色数据写入了数据文件、将提取到的纯色数据存储至了预定位置,完成了对待压缩图像的压缩。可见,本发明提供了一种针对纯色图像的单一颜色通道的图像压缩方法,通过该方法对纯色图像进行压缩,能在保证数据完整性的前提下大幅提高压缩率,从而能大幅降低纯色图像的大小,使其在存储和传输上更加便捷和高效。
[0054]
为了更好的理解本发明,下面结合图6通过一个具体的示例来对本发明的图像压缩方法的整个过程进行说明。在该示例中,待压缩图像为png格式的图标图像,具有a、r、g、b四个通道(即待压缩图像中的每个像素点都是一个argb的颜色通道值),具体压缩过程如下。
[0055]
第一步,获取待压缩图像的png文件,png文件中包括各像素的像素数据——a、r、g、b四个通道数据。
[0056]
第二步,检测待压缩图像是否为纯色图像。具体地,检测所有像素的r通道数据是否相同、g通道数据是否相同以及b通道数据是否相同,如果所有像素的r通道数据相同、g通道数据相同、b通道数据相同(即所有像素采用同一rgb数据),则判定待压缩图像为纯色图像,否则判定待压缩图像为非纯色图像,则结束。
[0057]
第三步,当判定待压缩图像为纯色图像时,遍历各像素的像素数据,剔除透明度(即a通道数据)为0的像素数据,并提取待压缩图像采用的统一的rgb数据(即上述实施例中的纯色数据)。
[0058]
第四步,对透明度不为0的像素数据进行整理,将argb四个通道用一个通道进行灰度存储,具体地,删除透明度不为0的像素的rgb数据,并将其透明度转换为灰度图像的亮度,转换时需适配灰度图像的深度。
[0059]
第五步,将透明度不为0的各像素的透明度所转换成的亮度写入待压缩图像的png文件中,并将待压缩图像所采用的统一的rgb数据写入待压缩图像的png文件的文件名的预定字段中,从而完成对待压缩图像的压缩。
[0060]
显然,对待压缩图像压缩后,其压缩数据中每个像素便只有一个灰色通道数据,而压缩前每个像素具有a、r、g、b四个通道数据。因此利用单一颜色通道的压缩方法对argb颜色模式的纯色图像进行压缩,能大约降低四分之三的原图像数据。下面以一个具体的例子来说明。
[0061]
当上述示出的待压缩图像的大小为1000
×
1000时,由于argb都是由8位存储,因此每个像素便需4个字节的物理磁盘数据来存储,从而存储上述待压缩图像所需的磁盘大小则为:4
×
1000
×
1000=4000000b=3906.3kb=3.9m。当利用本发明的单一颜色通道的图像压缩方法对待压缩图像进行压缩后,每个像素只有一个由8位存储的灰色通道数据,因此存储压缩后的图像所需的磁盘大小则为1
×
1000
×
1000=1000000b=976.6kb=0.9m。显然,利用本发明的单一颜色通道的压缩方法对待压缩图像进行压缩后,可将存储该图像的磁盘大小减少到四分之一,从而可以大幅度减少磁盘空间的负载量,对计算机优化物理磁盘,减少资源文件大小有很大的帮助。
[0062]
上述已示出本发明的针对纯色图像的单一颜色通道的图像压缩方法,针对于此,本发明还提供了一种相应的图像复原方法。即,提供了一种对采用上述单一颜色通道的图像压缩方法所压缩得到的图像进行复原的方法。
[0063]
图7示出了根据本发明一个实施例的图像复原方法700的流程图,方法700适于在计算设备(例如图1所示的计算设备100)中执行。如图7所示,该方法700始于710。其中,在执行710之前,应先判断待复原图像是否为采用上述单一颜色通道的图像压缩方法所压缩得到的压缩图像。具体地,可以通过如下方式检测。
[0064]
首先,获取待复原图像的数据文件,数据文件中包括待复原图像的像素格式。其中,像素格式包括gray(即灰度)格式、argb格式等。然后,检测待复原图像的像素格式是否为预定格式。其中,预定格式的像素只有一个颜色通道,因此预定格式可以为灰度格式,当然这只是一个示例,对此本发明不作限定。
[0065]
如果待复原图像的像素的格式不是预定格式,表明待复原图像不是单通道图像,则判定其不是采用上述单一颜色通道图像压缩方法进行的压缩,随之结束。而如果待复原图像的像素的格式为预定格式,则表明待复原图像为单通道图像。接着,检测预定位置中是否存储有纯色数据,即检测待复原图像压缩前是否为纯色图像。
[0066]
其中,预定位置可以为待复原图像的数据文件中的预定字段、待复原图像的数据文件的文件名中的预定字段或者打开待复原图像的应用程序的内部缓冲。即,该步骤可以为检测待复原图像的数据文件中的预定字段中是否存储有纯色数据,也可以为检测待复原图像的数据文件的文件名中的预定字段中是否存储有纯色数据,还可以为检测打开待复原图像的应用程序的内部缓冲中是否存储有纯色数据。
[0067]
如果预定位置中存储有纯色数据,表明待复原图像压缩前是一个纯色图像,随之
判定待复原图像为采用上述单一颜色通道图像压缩方法所压缩得到的压缩图像,随之,进入710。
[0068]
在710中,基于预定位置中存储的纯色数据,构造压缩图像压缩前各像素的各颜色通道的颜色数据。基于上述描述可知,预定位置中存储的纯色数据即为压缩图像(即待复原图像)压缩前其像素的除透明度通道之外的全部通道的颜色数据,即各像素的各颜色通道的颜色数据,则从预定位置中获取该纯色数据。
[0069]
具体地,如果预定位置为压缩图像的数据文件的文件名中的预定字段,则按照文件名的解析规则进行解析读取,如果预定位置为压缩图像的数据文件中的预定字段,则从数据文件中读取该预定字段,如果预定位置为打开压缩图像的应用程序的内部缓冲,则直接从该缓冲中进行读取。
[0070]
下面示出了从压缩图像的数据文件的预定字段中读取纯色数据的示例代码(在该示例中压缩图像为png格式,存储的纯色数据为rgb数据):#define rgbsig_name "rgb"static int read_color_sig_chunk(png_structp png_ptr, png_unknown_chunkp chunk){
ꢀꢀꢀꢀ
pixeldata *color_sig = (pixeldata *)png_get_user_chunk_ptr(png_ptr);
ꢀꢀꢀꢀ
if (!color_sig)
ꢀꢀꢀꢀꢀꢀꢀꢀ
return 0;
ꢀꢀꢀꢀ
if (!strcmp((const char *)chunk-》name, rgbsig_name))
ꢀꢀꢀꢀꢀꢀꢀꢀ
*color_sig = makepixel((channeldata)chunk-》data[0], (channeldata)chunk-》data[1], (channeldata)chunk-》data[2], 0);
ꢀꢀꢀꢀ
return 1;}png_set_keep_unknown_chunks(png_ptr, png_handle_chunk_always, const_cast《png_bytep》((const png_byte *)rgbsig_name), 1);png_set_read_user_chunk_fn(png_ptr, &data-》color_sig, read_color_sig_chunk);png_read_info(png_ptr, info_ptr);接下来,则基于获得的纯色数据,构造压缩图像压缩前各像素的各颜色通道的颜色数据。其中,在一些实施例中,可以将纯色数据拆分为各像素的各颜色通道的颜色数据。具体地,可以按照从高位到低位的顺序,将纯色数据中每预定数量位作为一个颜色通道的颜色数据。具体地,颜色通道可以包括红色通道、绿色通道和蓝色通道,相应地,纯色数据则为24位,预定数量则为8。如此,在将纯色数据拆分为各像素的各颜色通道的颜色数据时,可按照从高位到低位的顺序,将纯色数据的每8位作为一个颜色通道的颜色数据。进一步地,可以将纯色数据的高8位、中间8位以及低8位依次作为压缩图像压缩前各像素的红色通道数据、绿色通道数据和蓝色通道数据。当然,这只是一个示例,具体如何构造压缩图像压缩前各像素的各颜色通道的颜色数据,本发明不作限定。
[0071]
随后,进入720,基于压缩图像的数据文件的像素缓冲区中各像素的颜色通道的颜色数据,构造压缩图像压缩前各像素的透明度通道的透明度数据。其中,当压缩图像中像素的颜色通道的颜色数据的位数与压缩图像压缩前像素的透明度通道的透明度数据的位数一致时,可直接将当前像素缓冲区中每一个像素的颜色通道的颜色数据作为该像素压缩前的透明度通道的透明度数据。当然,这仅是一个示例,对此本发明不作限定。
[0072]
至此,便构造出了压缩图像压缩前各待压缩像素的透明度通道的透明度数据和各颜色通道的颜色数据,随后进入730,基于所构造的各像素的透明度通道的透明度数据及各颜色通道的颜色数据,对压缩图像进行复原。其中,可以在文件层或应用程序渲染层对压缩图像进行复原,具体如下。
[0073]
当在文件层对压缩图像进行复原时,首先,将压缩图像的像素缓冲区中各像素的颜色数据删除。
[0074]
然后,将像素缓冲区大小扩展为压缩前的大小,并将所构造的各像素的透明度通道的透明度数据及各颜色通道的颜色数据写入像素缓冲区中。即,在将所构造的各像素的各通道的数据写入像素缓冲区中时,先对压缩图像的数据文件的像素缓冲区中各像素的像素数据的位数进行扩容,具体扩容至压缩图像压缩前各像素的像素数据的位数,然后再将所构造的各像素的像素数据(即透明度通道的透明度数据及各颜色通道的颜色数据)写入该像素对应的像素缓冲区中。其中,像素和缓冲区一一对应,因此在将所构造的各像素的像素数据写入其对应的像素缓冲区中后,还可以进一步地检测是否存在未填写像素数据的缓冲区,如果存在,则表明压缩图像在压缩前存在透明度为0的像素,且当前像素数据为空的像素缓冲区所对应的像素即为压缩图像压缩前中透明度为0的像素,则随之在当前像素数据为空的像素缓冲区中填入相应的像素数据,具体地,将0作为透明度数据,将纯色数据作为全部颜色通道的颜色数据。至此,便恢复了压缩图像压缩前各像素的像素数据。
[0075]
最后,将预定位置中存储的纯色数据删除。
[0076]
下面作一示例,压缩图像为灰度图像,压缩图像压缩前为argb颜色模式的图像,则先将压缩图像的像素缓冲区中各像素的像素数据的位数从8bit扩容到32bit,然后再将预定位置存储的压缩图像压缩前共用的rgb数据(即上述的纯色数据)作为各像素的rgb数据(即r、g、b通道数据),将压缩图像的像素缓冲区中本身存储的各像素的亮度作为压缩图像压缩前各像素的透明度数据(即a通道数据)写入对应的像素缓冲区中,如果还存在数据为空的像素缓冲区,则将0作为透明度数据,将预定位置存储的rgb数据作为r、g、b通道数据进行填充,从而构造出压缩前的argb数据并存储为argb格式,如此便将压缩图像恢复成了其压缩前的原始图像。
[0077]
其中,上述示出的将压缩图像的像素缓冲区中的像素数据的位数从8bit扩容到32bit,再将通用的rgb数据以及存储的alpha数据写入到像素缓冲区中,正确构造出压缩前的argb数据并存储为argb格式的示例性代码如下:void pnghander::restorepngdata(){
ꢀꢀꢀꢀ
unsigned long expandedlength = data-》nbytes * sizeof(pixeldata);
ꢀꢀꢀꢀ
channeldata *buffer = new channeldata[expandedlength];
ꢀꢀꢀꢀ
channeldata *b = data-》bytes;
ꢀꢀꢀꢀ
pixeldata *dest = (pixeldata *)buffer;
ꢀꢀꢀꢀ
for (channeldata *p = b; p 《 b data-》nbytes; p, dest) {
ꢀꢀꢀꢀꢀꢀꢀꢀ
*dest = makepixel(redchannel(data-》color_sig), greenchannel(data-》color_sig), bluechannel(data-》color_sig), *p);
ꢀꢀ
// only save the alpha channel.
ꢀꢀꢀꢀ
}
ꢀꢀꢀꢀ
delete[] data-》bytes;
ꢀꢀꢀꢀ
data-》bytes = buffer;
ꢀꢀꢀꢀ
data-》nbytes = expandedlength;
ꢀꢀꢀꢀ
data-》bytes_per_line *= sizeof(pixeldata);
ꢀꢀ
// only save alpha.}至此,便在文件层实现了对压缩图像的复原。可见,文件层数据复原即将压缩文件恢复到和原始文件大小一致的文件。
[0078]
为了更好的理解本发明在文件层复原图像的方法,下面结合图8通过一个具体的示例来对此复原方法的整个过程进行说明。其中,在该示例中,预定格式为gray格式(即只有待复原图像为灰度图像时才能进行复原),纯色数据为rgb数据,具体如下。
[0079]
首先,读取待复原图像的数据文件,其中该数据文件中包括待复原图像的像素格式。然后,判断待复原图像的像素格式否为gray格式,如果是,则表明待复原图像为灰度图像,随之检测预定位置中是否存储有通用的rgb数据,如果预定位置中也存储有通用的rgb数据,则判定待复原图像可复原,即待复原图像为采用上述单一颜色通道的图像压缩方法压缩得到的压缩图像。随之,从预定位置中提取通用的rgb数据。接着,扩充待复原图像的数据文件中的像素数据至32位。最后,利用所提取的通用的rgb数据以及复原图像的数据文件中本身所存储的各像素的亮度数据填充argb数据,并存储为argb格式。该示例的示例性代码如下:bool pnghander::restorepng(const std::string &src_file_name, const std::string &out_file_name){
ꢀꢀꢀꢀ
if (!readpngdata(src_file_name))
ꢀꢀꢀꢀꢀꢀꢀꢀ
return false;
ꢀꢀꢀꢀ
if (data-》color_type != png_color_type_gray)
ꢀꢀꢀꢀꢀꢀꢀꢀ
return false;
ꢀꢀ
// not a grayscale image.
ꢀꢀꢀꢀ
restorepngdata();
ꢀꢀꢀꢀ
writepngdata(out_file_name, png_color_type_rgb_alpha, 0, 0);
ꢀꢀꢀꢀ
return true;}另外,本发明还利用上述示出的单一颜色通道的图像压缩方法和文件层的图像复原方法,对一纯色图标图像先后进行了压缩和复原,压缩后的图标图像和复原后的图标图像的数据如下表2: 像素大小文件大小像素格式是否进行png压缩是否支持预览
原图标图像225*2002755bargb是是压缩后图像225*2001857bgray是是复原后图像225*2002755bargb是是表2下面对在应用渲染层对压缩图像进行复原的方法进行说明。应用渲染层复原图像,即在软件层进行渲染,兼容压缩文件直接将图片渲染到所需要展示的应用程序界面上。具体地,在本实施例中,可以根据所构造的各像素的透明度通道的透明度数据及各颜色通道的颜色数据,利用绘制系统将各像素渲染至打开压缩图像的应用程序的界面中。其中,绘制系统可以为qt提供的应用程序绘制系统。即,当某个应用程序需要使用压缩图像时,通过qt绘制系统中提供的图像合成模式,将各像素渲染至该应用程序的界面中。
[0080]
在此,对图像合成(image compositing)进行一下说明。图像合成是用于将源图像中的像素与目标图像中的像素进行合并形成最终图像的技术。本实施例中使用到的图像合成模式为源图像重合模式(source in),当源图像和目标图像有重合区域时,最终图像仅保存原图像的重合区域。虽源图像重合模式和目标图像重合模式(destination in)的最终图像大小区域一致,但当图像有alpha通道时,不同的是alpha通道的跟随情况不同,source in的alpha通道跟随目标图像的alpha通道变化(即sourcein模式能够保留源图像的alpha通道并合成目标颜色到原图像中),而destination in的alpha通道跟随源图像的alpha通道变化。
[0081]
下面以压缩图像为png格式、像素格式为gray格式为例作一示例,使用软件渲染时,只需将读出的gray格式转换成alpha8格式,然而由于其存储的内部像素格式、大小和数据都一致,因此可以直接使用源文件数据进行替代,转换成功后通过qimage对象渲染到应用程序的界面中。该示例的示例性代码如下:qimage layer(restorefilename);qimage restoreimage(layer.bits(), layer.width(), layer.width(), layer.bytesperline(), qimage::format_alpha8);qimage outimage(layer.width(), layer.height(), qimage::format_argb32);outimage.fill(qt::transparent);qpainter render;render.begin(&outimage);render.drawimage(outimage.rect(), restoreimage);render.setcompositionmode(qpainter::compositionmode_sourcein);render.fillrect(restoreimage.rect(), commonrgbcolor);render.end();需说明的是,上述仅是一示例,本发明并不仅局限于png格式的图像,qt组件提供了对大多数图像格式的兼容,因此本发明支持大多数的图像格式。其中,基于qt的多格式的通用压缩复原的示例性代码如下://基于qt的压缩static bool convertimageto(const qstring &originpath, const qstring &
targetpath){
ꢀꢀꢀꢀ
qimage originimage(originpath);
ꢀꢀꢀꢀ
if (originimage.isnull())
ꢀꢀꢀꢀꢀꢀꢀꢀ
return false;
ꢀꢀꢀꢀ
const auto fi = qfileinfo(originpath);
ꢀꢀꢀꢀ
const qstring &suffix = fi.suffix();
ꢀꢀꢀꢀ
if ((originimage.width() % 2) || (originimage.height() % 2))
ꢀꢀꢀꢀꢀꢀꢀꢀ
return false;
ꢀꢀꢀꢀ
auto tmp = originimage.converttoformat(qimage::format_alpha8);
ꢀꢀꢀꢀ
qimage alpha(tmp.constbits(), tmp.width(), tmp.height(), tmp.bytesperline(), qimage::format_grayscale8);
ꢀꢀꢀꢀ
return alpha.save(targetpath, suffix.tolocal8bit());}//基于qt的复原static bool convertimagefrom(const qstring &originpath, const qstring &targetpath) {
ꢀꢀꢀꢀ
qstring path(originpath);
ꢀꢀꢀꢀ
auto fi = qfileinfo(originpath);
ꢀꢀꢀꢀ
qstring suffix = fi.suffix();
ꢀꢀꢀꢀ
if (suffix.compare(alpha8string, qt::caseinsensitive))
ꢀꢀꢀꢀꢀꢀꢀꢀ
return false;
ꢀꢀ
// no convert to alpha8.
ꢀꢀꢀꢀ
path.remove(qlatin1char('.') fi.suffix());
ꢀꢀꢀꢀ
qimage originimage(originpath);
ꢀꢀꢀꢀ
if (originpath.isnull() || originimage.format() != qimage::format_grayscale8)
ꢀꢀꢀꢀꢀꢀꢀꢀ
return false;
ꢀꢀꢀꢀ
suffix = qfileinfo(path).suffix();
ꢀꢀꢀꢀ
qimage targetimage(originimage.bits(), originimage.width(), originimage.height(),
ꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀꢀ
originimage.bytesperline(), qimage::format_alpha8);
ꢀꢀꢀꢀ
return targetimage.save(targetpath, suffix.tolocal8bit());}至此,便在软件层实现了对压缩图像的复原。另外,本发明还利用上述示出的单一颜色通道的图像压缩方法和软件层的图像复原方法,对不同大小、格式的纯色图标图像先后进行了压缩和复原,压缩后的图标图像和压缩前的图标图像的大小对比如下表3:像素大小图像格式原始文件大小压缩文件大小225*200png4451b1878b
225*200webp2318b1316b563*500png17049b5526b563*500webp6172b2992b1125*1000png46905b11754b1125*1000webp12772b6792b2250*2000png137155b25728b2250*2000webp29226b17164b表3可见,不同格式的图像由于其本身存在数据压缩的情况,压缩效果不尽相同,但基于本发明的单一通道的图像压缩方法以及对应的图像复原方法最终都能减少原图的大小并实现无损复原。
[0082]
另外,在此还需对待复原图像的像素格式为预定格式,但预定位置中未存储有纯色数据的情况进行一下说明。这种情况在文件层复原时,尽管待复原图像是一个单通道图像,但由于没有纯色数据,无法进行数据填充,因此无法进行复原。然而,这种情况在软件渲染时较为特殊,这种场景下应用程序可以动态指定需要渲染的颜色,即应用程序自定义需要的颜色(如rgb颜色),然后再使用自定义数据进行动态合成从而实现无损复原,因此该情况在软件层可进行复原。
[0083]
该方案在应用程序无需关心图片具体像素点颜色时非常有用,例如程序需要在鼠标点击和非点击状态下切换具体某个图标的前景颜色时,它能在复原该文件时对图标进行前景色渲染,再根据程序所需的不同状态选择使用不同的颜色进行最终图像合成。
[0084]
为了更好的理解本发明的图像复原过程,下面结合图9又给出了一个具体的示例。在该示例中,预定格式为灰度格式,纯色数据为rgb数据,具体如下。
[0085]
首先,读取待复原图像的图像数据,图像数据中包括待复原图像的像素格式。然后,检测待复原图像的像素格式是否为灰度格式。如果不是,则判定待复原图像不是利用上述单一颜色通道图像压缩方法压缩得到的压缩图像,因此待复原图像不可复原。如果是,则接着检测预定位置是否存储有通用的rgb数据。如果预定位置中存储有通用的rgb数据,则判定待复原图像是利用上述单一颜色通道图像压缩方法压缩得到的压缩图像,因此待复原图像既可在文件层复原也可在软件层渲染复原,而如果预定位置中未存储有通用的rgb数据,则判断是否进行软件层渲染复原。如果进行软件层渲染复原,则进行复原,否则判定待复原图像不可复原。
[0086]
其中,关于本实施例在判定待复原图像可复原后,对其进行复原的具体细节可参考上述基于图7和图8的描述,在此不再赘述。
[0087]
本发明针对纯色图像提供了一种单一颜色通道的图像压缩方法,该方法可以在不改变原始图像格式的条件下,大幅提高图像的压缩率。并且,本发明还提供了相应的图像复原方法,其能对使用上述单一颜色通道的图像压缩方法压缩得到的图像进行无损复原。
[0088]
这里描述的各种技术可结合硬件或软件,或者它们的组合一起实现。从而,本发明的方法和设备,或者本发明的方法和设备的某些方面或部分可采取嵌入有形媒介,例如可移动硬盘、u盘、软盘、cd-rom或者其它任意机器可读的存储介质中的程序代码(即指令)的形式,其中当程序被载入诸如计算机之类的机器,并被所述机器执行时,所述机器变成实践
本发明的设备。
[0089]
在程序代码在可编程计算机上执行的情况下,计算设备一般包括处理器、处理器可读的存储介质(包括易失性和非易失性存储器和/或存储元件),至少一个输入装置,和至少一个输出装置。其中,存储器被配置用于存储程序代码;处理器被配置用于根据该存储器中存储的所述程序代码中的指令,执行本发明的图像压缩方法或图像复原方法。
[0090]
以示例而非限制的方式,可读介质包括可读存储介质和通信介质。可读存储介质存储诸如计算机可读指令、数据结构、程序模块或其它数据等信息。通信介质一般以诸如载波或其它传输机制等已调制数据信号来体现计算机可读指令、数据结构、程序模块或其它数据,并且包括任何信息传递介质。以上的任一种的组合也包括在可读介质的范围之内。
[0091]
在此处所提供的说明书中,算法和显示不与任何特定计算机、虚拟系统或者其它设备固有相关。各种通用系统也可以与本发明的示例一起使用。根据上面的描述,构造这类系统所要求的结构是显而易见的。此外,本发明也不针对任何特定编程语言。应当明白,可以利用各种编程语言实现在此描述的本发明的内容,并且上面对特定语言所做的描述是为了披露本发明的最佳实施方式。
[0092]
在此处所提供的说明书中,说明了大量具体细节。然而,能够理解,本发明的实施例可以在没有这些具体细节的情况下被实践。在一些实例中,并未详细示出公知的方法、结构和技术,以便不模糊对本说明书的理解。
[0093]
应当理解,为了精简本公开并帮助理解各个发明方面中的一个或多个,在上面对本发明的示例性实施例的描述中,本发明的各个特征有时被一起分组到单个实施例、图、或者对其的描述中。然而,并不应将该公开的方法解释成反映如下意图:即所要求保护的本发明要求比在每个权利要求中所明确记载的特征更多特征。
[0094]
本领域那些技术人员应当理解在本文所公开的示例中的设备的模块或单元或组件可以布置在如该实施例中所描述的设备中,或者可替换地可以定位在与该示例中的设备不同的一个或多个设备中。前述示例中的模块可以组合为一个模块或者此外可以分成多个子模块。
[0095]
本领域那些技术人员可以理解,可以对实施例中的设备中的模块进行自适应性地改变并且把它们设置在与该实施例不同的一个或多个设备中。可以把实施例中的模块或单元或组件组合成一个模块或单元或组件,以及此外可以把它们分成多个子模块或子单元或子组件。除了这样的特征和/或过程或者单元中的至少一些是相互排斥之外,可以采用任何组合对本说明书(包括伴随的权利要求、摘要和附图)中公开的所有特征以及如此公开的任何方法或者设备的所有过程或单元进行组合。除非另外明确陈述,本说明书(包括伴随的权利要求、摘要和附图)中公开的每个特征可以由提供相同、等同或相似目的的替代特征来代替。
[0096]
此外,本领域的技术人员能够理解,尽管在此所述的一些实施例包括其它实施例中所包括的某些特征而不是其它特征,但是不同实施例的特征的组合意味着处于本发明的范围之内并且形成不同的实施例。
[0097]
此外,所述实施例中的一些在此被描述成可以由计算机系统的处理器或者由执行所述功能的其它装置实施的方法或方法元素的组合。因此,具有用于实施所述方法或方法元素的必要指令的处理器形成用于实施该方法或方法元素的装置。此外,装置实施例的在
此所述的元素是如下装置的例子:该装置用于实施由为了实施该发明的目的的元素所执行的功能。
[0098]
如在此所使用的那样,除非另行规定,使用序数词“第一”、“第二”、“第三”等等来描述普通对象仅仅表示涉及类似对象的不同实例,并且并不意图暗示这样被描述的对象必须具有时间上、空间上、排序方面或者以任意其它方式的给定顺序。
[0099]
尽管根据有限数量的实施例描述了本发明,但是受益于上面的描述,本技术领域内的技术人员明白,在由此描述的本发明的范围内,可以设想其它实施例。此外,应当注意,本说明书中使用的语言主要是为了可读性和教导的目的而选择的,而不是为了解释或者限定本发明的主题而选择的。因此,在不偏离所附权利要求书的范围和精神的情况下,对于本技术领域的普通技术人员来说许多修改和变更都是显而易见的。对于本发明的范围,对本发明所做的公开是说明性的,而非限制性的,本发明的范围由所附权利要求书限定。
再多了解一些

本文用于创业者技术爱好者查询,仅供学习研究,如用于商业用途,请联系技术所有人。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表

相关文献