图片解码方法及装置与流程

文档序号:11961247阅读:478来源:国知局
图片解码方法及装置与流程

本发明实施例涉及图片解码技术领域,特别涉及一种图片解码方法及装置。



背景技术:

应用程序在运行过程中,经常需要从互联网处获取图片并进行显示。伴随着图片格式种类的不断增多,应用程序需要支持的图片格式也越来越多。

由于系统支持的图片格式有限,为了使应用程序支持更多的图片格式,开发人员将图片解码器移植到应用程序中,并在应用程序代码中增加相应的解码器接口以供调用。应用程序显示图片时,即通过解码器接口调用相应的图片解码器对图片进行解码,并根据解码出的数据进行图像渲染。

在实现本发明实施例的过程中,发明人发现上述技术至少存在以下问题:

每次移植新的图片解码器来支持新增图片格式的图片时,都需要在程序代码中新增解码器接口,灵活性差且开发效率较低。



技术实现要素:

为了解决现有技术中每次移植新的图片解码器来支持新增图片格式的图片时,都需要在程序代码中新增解码器接口,灵活性差且效率较低的问题,本发明实施例提供了一种图片解码方法及装置。所述技术方案如下:

根据本发明实施例的第一方面,提供一种图片解码方法,该方法包括:

获取新增图片格式的图片;

在Skia(中文:安卓系统底层图像库)的解码器链表中查找用于解码该图片的新增解码器,解码器链表中包含用于解码不同图片格式的解码器;

利用新增解码器对该图片进行解码。

根据本发明实施例的第而方面,提供一种图片解码装置,该装置包括:

获取模块,用于获取新增图片格式的图片;

查找模块,用于在Skia的解码器链表中查找用于解码该图片的新增解码器,解码器链表中包含用于解码不同图片格式的解码器;

解码模块,用于利用新增解码器对该图片进行解码。

本发明实施例提供的技术方案带来的有益效果是:

通过将新增解码器添加到Skia中,当需要对新增图片格式的图片进行解码时,从Skia的解码器链表中查找用于解码该图片的新增解码器,并进一步利用该解码器对图片进行解码;解决了每次移植新的图片解码器来支持新增图片格式的图片时,都需要在程序代码中新增解码器接口,灵活性差且开发效率较低的问题;达到了利用Skia中添加的新增解码器对新增图片格式的图片进行解码,避免了在程序代码中增加相应的解码器接口,从而提高添加解码器时的灵活性和开发效率。

附图说明

为了更清楚地说明本发明实施例中的技术方案,下面将对实施例描述中所需要使用的附图作简单地介绍,显而易见地,下面描述中的附图仅仅是本发明的一些实施例,对于本领域普通技术人员来讲,在不付出创造性劳动的前提下,还可以根据这些附图获得其他的附图。

图1示出了本发明一个实施例提供的图片解码方法的流程图;

图2A示出了本发明另一个实施例提供的图片解码方法的流程图;

图2B示出了本发明再一个实施例提供的图片解码方法的流程图;

图2C是图2B所示图片解码方法所涉及的解码器插入过程的实施示意图;

图2D是图2B所述图片解码方法所涉及的解码器查找过程的实施示意图;

图3示出了本发明一个实施例提供的图片解码装置的结构方框图;

图4示出了本发明另一个实施例提供的图片解码装置的结构方框图。

具体实施方式

为使本发明的目的、技术方案和优点更加清楚,下面将结合附图对本发明实施方式作进一步地详细描述。

为了方便理解,下面对本发明实施例中出现的名词进行解释。

Skia:即安卓系统底层图像库,是一种C++的开源2D向量图像处理函数库,包括字型处理、坐标转换和位图处理等功能,通常应用于Android(安卓)系统,利用Skia可以对JPEG、PNG、BMP或GIF等图片格式的图片进行编解码。

native层:Android系统中,native层(采用C/C++语言编写)与上层Java层(采用Java语言编写)进行通信,用于处理较为复杂的运算以及访问操作系统底层(比如系统硬件)。通常情况下,上述Skia即位于native层。

JNI(Java Native Interface,Java本地接口):即位于Java层和native层之间的接口,通过提供若干API(Application Programming Interface,应用程序编程接口)实现Java层与native层之间的通信。比如,当Java程序需要执行一个复杂运算时,由于Java代码的实现效率较低,而C/C++代码的实现效率较高,因此可以由native层完成复杂运算,并通过native层与Java层之间的JNI将运算结果返回给Java层。

本发明各个实施例提供的图片解码方法,用于Android设备中,该Android设备可以是安装有Android系统的智能手机、平板电脑、MP3播放器(Moving Picture Experts Group Audio Layer III,动态影像专家压缩标准音频层面3)或MP4(Moving Picture Experts Group Audio Layer IV,动态影像专家压缩标准音频层面4)播放器等等。需要说明的是,该Android设备也可以是运行有Android虚拟机的个人计算机,本发明实施例并不对此进行限定。

为了方便描述,下述各个实施例以图片解码方法用于Android设备为例进行示意性说明。

请参考图1,其示出了本发明一个实施例提供的图片解码方法的流程图,本实施例以该图片解码方法用于Android设备为例进行说明,该方法包括:

步骤101,获取图片,该图片为新增图片格式的图片。

其中,该新增图片格式指除Android系统所支持图片格式以外的图片格式,即Android系统所不支持的图片格式。比如,Android系统中支持的图片格式包括JPEG、PNG、BMP和GIF,该新增图片格式即指除JPEG、PNG、BMP和GIF以外的图片格式,例如,WebP格式,本发明并不对新增图片格式的具体类型进行限定。

该图片可以是Android设备中应用程序自带的布局图片(布局文件中的图片,比如可扩展标记语言xml文件中的图片),也可以是应用程序从网络下载的图片,本公开实施例并不对图片的来源进行限定。

步骤102,在Skia的解码器链表中查找用于解码该图片的新增解码器,解码器链表中包含用于解码不同图片格式的解码器。

Skia中包括至少一种解码器,且不同的解码器用于解码不同图片格式的图片。比如,Skia中包括用于解码PNG图片的PNG解码器以及用于解码JPEG图片的JPEG解码器。

为了能够对新增图片格式的图片进行解码,Skia中预先添加了用于解码该新增图片格式的新增解码器。比如,Skia中已包含PNG解码器和JPEG解码器,为了实现对WebP图片的解码,Skia中需要预先添加WebP解码器。

Skia中的解码器以链表的形式存储在解码器链表中,当应用程序需要利用Skia中的解码器进行图片解码时,即通过遍历解码器链表的方式,查找相应的解码器。

步骤103,利用新增解码器对该图片进行解码。

进一步的,应用程序利用查找到的新增解码器对图片进行解码,并根据解码得到的图片数据进行图像绘制,从而在Android设备中显示该图片。

有别于现有技术中通过程序代码中的解码器接口调用移植的解码器进行图片解码,本发明实施例提供的图片解码方法中,利用切面式编程思想,将新增的解码器插入Skia的解码器链表中,在进行图片解码时,只需要从解码器链表中查找相应的解码器进行解码即可,而无需借助程序代码中的解码器接口进行解码器调用(需要开发者了解并使用相关的解码器接口,学习成本较高),从而避免每次添加解码器都需要对程序代码进行修改,简化了添加解码器流程。

综上所述,本实施例提供的图片解码方法,通过将新增解码器添加到Skia中,当需要对新增图片格式的图片进行解码时,从Skia的解码器链表中查找用于解码该图片的新增解码器,并进一步利用该解码器对图片进行解码;解决了每次移植新的图片解码器来支持新增图片格式的图片时,都需要在程序代码中新增解码器接口,灵活性差且开发效率较低的问题;达到了利用Skia中添加的新增解码器对新增图片格式的图片进行解码,避免了在程序代码中增加相应的解码器接口,从而提高添加解码器时的灵活性和开发效率。

请参考图2A,其示出了本发明另一个实施例提供的图片解码方法的流程图,本实施例以该图片解码方法用于Android设备为例进行说明,该方法包括:

步骤201,根据Skia中已有解码器的实现方式,创建新增解码器。

WebP图片相较于PNG图片和JPEG图片的压缩率更高(WebP图片的压缩体积大约为JPEG图片的2/3),因此在传输速率以及传输耗费流量方面,WebP图片相较于JPEG图片具有明显优势,具有广阔的使用前景,但是目前仅Android4.2以上的系统才能够支持WebP图片解码。为了使Android 4.2以下的系统也能够支持WebP图片解码,本实施例中,Android底层Skia中需要增加WebP图片格式对应的解码器。

通常情况下,Android底层Skia中包括PNG、JPEG、GIF等图片格式对应的解码器,这些已有解码器的整体实现方式相似,在解码逻辑上存在差异。因此,在构建新增解码器(WebP解码器)时,可以根据已有解码器的实现方式,封装一个新的解码器,并在该解码器中实现WebP图片格式对应的解码逻辑,从而构建出的新增解码器。本发明并不对构建新增解码器的具体实施方式进行限定。

步骤202,将新增解码器插入解码器链表中。

Skia中存储有解码器链表,该解码器链表中包含已支持图片格式对应的解码器,其中,各个解码器以解码器工厂方法的形式存储在解码器链表中,且该解码器链表的节点中包含已支持图片格式对应的解码器工厂方法函数指针,用于指示各个解码器工厂方法。为了方便描述,下述实施例以解码器链表用于存储解码器为例进行说明。

应用程序利用Skia中的解码器进行图片解码时,即通过遍历解码器链表的方式查找用于解码该图片的解码器,利用查找到的解码器(工厂方法)创建解码器实例,并进一步利用该解码器实例对图片进行解码。因此,在构建完新增解码器后,开发人员需要编写对应的新增解码器工厂方法,从而将新增解码器工厂方法函数指针写入链表节点并插入解码器链表中,方便后续解码时进行遍历查找。

比如,该新增解码器对应的链表节点(写入有新增解码器工厂方法函数指针)可以被插入解码器链表的头部。本实施例并不对新增解码器插入的具体位置进行限定。

上述步骤201和步骤202通过Hook(钩)Skia的解码器链表,将新增解码器插入解码器链表中,从而完成解码器的添加(即Android 4.2以下系统中的应用程序也能够支持显示WebP图片),整个添加过程仅需要对Skia进行处理,并未涉及对程序代码的修改,相较于现有技术中“移植解码器+增加解码器接口”的解码器添加流程,本实施例的解码器添加效率更高且灵活性更强。

步骤203,获取图片,该图片为新增图片格式的图片。

比如,该图片可以是应用程序根据布局文件(比如xml文件)中布局图片存储路径获取的布局图片(新增图片格式WebP),也可以是应用程序从互联网获取的网络图片(新增图片格式WebP)。

步骤204,在Skia的解码器链表中查找用于解码该图片的新增解码器,解码器链表中包含用于解码不同图片格式的解码器。

由于新增解码器已被插入Skia的解码器链表中,因此,当需要对新增图片格式的图片进行解码显示时,应用程序即可在解码器链表中查找到用于解码该新增图片格式的新增解码器(工厂方法),并进一步根据新增解码器工厂方法创建新增解码器实例。

步骤205,利用新增解码器对该图片进行解码。

在一种可能的实施中,本步骤可以包括如下步骤。

步骤205A,根据新增解码器创建解码器实例。

查找到新增解码器后,Skia即根据该解码器创建一个解码器实例,并利用该解码器实例对图片进行解码。

在具体的实施方式中,Skia在获得图片的数据流后,以数据流为输入参数遍历解码器链表并调用该解码器链表中的每个解码器工厂方法,若解码器工厂方法返回有效解码器实例(由相应的解码器工厂方法创建),则确定找到用于解码该图片的解码器,遍历结束,进一步利用返回的创建解码器实例来解码图片;若遍历了解码器链表中的所有解码器工厂方法但仍未返回有效解码器实例,则确定该解码器链表中不包含用于解码该图片的解码器工厂方法,并提示解码失败。

步骤205B,通过解码器实例对图片进行解码,得到图片的图片数据,图片数据用于构造Bitmap对象进行图像绘制。

通过解码器实例对图片进行解码后,能够得到诸如图片尺寸(像素)、色深、像素颜色等图片数据,使用这些图片数据构造出Bitmap对象即进行图像绘制,并最终在Android设备上显示该图片。

现有技术中,由于应用程序布局文件中引用的布局图片无法通过调用解码器接口的方式进行解码,导致布局图片无法采用新增图片格式;而本实施例中,当布局文件中的布局图片采用新增图片格式时,应用程序也可以通过Skia中的新增解码器对该布局图片进行解码,从而扩大解码器的应用范围。

本实施例仅以获取到的图片为新增图片格式WebP为例进行说明,在其他可能的实施方式中,当获取到的图片是其他图片格式(比如TIFF、APNG或PCX等等)时,应用程序通过解码器链表中相应的解码器对其进行解码,本实施例并不对此构成限定。

综上所述,本实施例提供的图片解码方法,通过将新增解码器添加到Skia中,当需要对新增图片格式的图片进行解码时,从Skia的解码器链表中查找用于解码该图片的新增解码器,并进一步利用该解码器对图片进行解码;解决了每次移植新的图片解码器来支持新增图片格式的图片时,都需要在程序代码中新增解码器接口,灵活性差且开发效率较低的问题;达到了利用Skia中添加的新增解码器对新增图片格式的图片进行解码,避免了在程序代码中增加相应的解码器接口,从而提高添加解码器时的灵活性和开发效率。

本实施例中,通过Hook Skia的解码器链表,将新增解码器插入解码器链表中,从而完成解码器的添加,避免了对程序代码进行修改,从而提高了添加解码器的效率和灵活性。

本实施例中,不论是网络图片、本地图片还是布局文件中引用的布局图片,均可以通过Skia中的解码器对进行解码,相较于现有技术中移植的解码器使用范围更大。

Android底层Skia的实现代码中定义有变量gHead,gHead是指向解码器链表头部的头指针。利用Skia中的解码器进行图片解码时,Skia即通过该gHead头指针在解码器链表中遍历查找。相似的,Android应用程序可以利用该gHead头指针向解码器链表中插入新增解码器。在一种可能的实施方式中,如图2B所示,上述步骤202可以包括如下步骤。

步骤202A,在native层声明gHead为外部变量。

由于gHead在C++中是一个全局变量,因此在添加解码器阶段,通过在应用程序的native层声明gHead为外部变量,可以实现透过native层访问Skia中的解码器链表。

在一种可能的实施方式中,应用程序的native层实现通过extern(外部)声明的方式,声明gHead是native层(其它模块定义)的一个外部变量。

比如,应用程序的native层可以通过如下代码实现声明gHead是native层(其它模块定义)的一个外部变量:

Typedef SkTRegistry<SkImageDecoder*,SkStream*>DecodeReg;

extern template DecodeReg*SkTRegistry<SkImageDecoder*,SkStream*>::gHead;

步骤202B,通过gHead访问Skia的解码器链表。

在native层实现gHead外部变量声明后,native层实现即可通过gHead访问Skia中的解码器链表。并且,由于Skia中的gHead指向解码器链表头部,native层实现可以从解码器链表的头部开始访问。

步骤202C,将新增解码器插入解码器链表的头部。

进一步的,应用程序native层从解码器链表的头部开始访问,并将上述步骤201构建的新增解码器(工厂方法)插入解码器链表的头部。

比如,如图2C所示,Skia的解码器链表中原先包含PNG解码器、JPEG解码器、BMP解码器和GIF解码器等,当需要向Skia中增加WebP解码器时,应用程序native层即通过gHead从头部开始访问该解码器链表,并将新增的WebP解码器工厂方法添加到解码器链表中。

步骤202D,将新增解码器对应的动态链接库和解码器链表所在动态链接库进行链接。

为了保证新增解码器的正常运行,将新增解码器(工厂方法)插入解码器链表的同时,需要将新增解码器对应的动态链接库链接到该解码器链表,使得新增解码器运行时,能够调用相应动态链接库中的方法函数,避免运行解码器时出现异常。其中,该解码器链表所在动态链接库为libskia.so文件。

相应的,在对图片解码进行解码时,Skia可以借助gHead头指针从解码器链表中遍历查找相应的解码器对图片进行解码。在一种可能的实施方式中,如图2B所示,上述步骤204可以包括如下步骤。

步骤204A,通过JNI调用native层。

Android应用程序可以大致分为Java层和native层,其中,Java层和native层之间通过JNI进行数据交互。如图2D所示,应用程序在Java层获取到图片时,通过JNI调用native层对图片进行解码。

步骤204B,通过native层声明的gHead访问Skia的解码器链表。

由于native层声明了gHead,因此如图2D所示,当native层接收到对图片进行解码的指示后,可以通过该gHead调用Skia,并最终通过gHead对Skia中的解码器链表进行访问。

比如,native层通过gHead遍历Skia解码器链表可以通过如下代码实现:

步骤204C,根据新增图片格式从解码器链表的头部获取新增解码器。

进一步的,应用程序native层通过gHead访问解码器链表时,根据图片的图片格式,在解码器工厂方法链表中查找与该图片格式匹配的解码器工厂。

如图2D所示,由于新增解码器被插入解码器链表的头部,因此,当需要解码的图片为新增图片格式时,应用程序native层即根据该新增图片格式从解码器链表的头部获取新增解码器,并利用该新增解码器进行图片解码。

本实施例中,在添加解码器阶段,利用解码器链表中的gHead头指针向解码器链表头部插入新增解码器,提高添加解码器时的灵活性;在查找解码器阶段,利用该gHead头指针遍历查找解码器链表查找匹配的解码器,提高了查找解码器的效率。

需要说明的是,上述实施例中仅以新增图片格式为WebP,新增解码器为WebP解码器为例进行示意性说明,并不对本发明构成限定。

下述为本发明装置实施例,对于装置实施例中未详尽描述的细节,可以参考上述一一对应的方法实施例。

请参考图3,其示出了本发明一个实施例提供的图片解码装置的结构方框图。该图片解码装置通过硬件或者软硬件的结合实现成为Android设备的全部或者一部分。该图片解码装置包括:

获取模块310,用于获取图片,所述图片为新增图片格式的图片;

查找模块320,用于在安卓底层图像库Skia的解码器链表中查找用于解码所述图片的新增解码器,所述解码器链表中包含用于解码不同图片格式的解码器;

解码模块330,用于利用所述新增解码器对所述图片进行解码。

综上所述,本实施例提供的图片解码装置,通过将新增解码器添加到Skia中,当需要对新增图片格式的图片进行解码时,从Skia的解码器链表中查找用于解码该图片的新增解码器,并进一步利用该解码器对图片进行解码;解决了每次移植新的图片解码器来支持新增图片格式的图片时,都需要在程序代码中新增解码器接口,灵活性差且效率较低的问题;达到了利用Skia中添加的新增解码器对新增图片格式的图片进行解码,避免了在程序代码中增加相应的解码器接口,从而提高添加解码器时的灵活性和效率。

请参考图4,其示出了本发明另一个实施例提供的图片解码装置的结构方框图。该图片解码装置通过硬件或者软硬件的结合实现成为Android设备的全部或者一部分。该图片解码装置包括:

获取模块410,用于获取图片,所述图片为新增图片格式的图片;

查找模块420,用于在安卓底层图像库Skia的解码器链表中查找用于解码所述图片的新增解码器,所述解码器链表中包含用于解码不同图片格式的解码器;

解码模块430,用于利用所述新增解码器对所述图片进行解码。

可选的,该装置,包括:

创建模块440,被配置为根据所述Skia中已有解码器的实现方式,创建所述新增解码器;

插入模块450,被配置为将所述新增解码器插入所述解码器链表中。

可选的,所述Skia中定义有变量gHead,所述gHead是指向所述解码器链表头部的头指针;

所述插入模块450,包括:

声明单元451,用于在本地native层声明所述gHead为外部变量;

第一访问单元452,用于通过所述gHead访问所述Skia的所述解码器链表;

插入单元453,用于将所述新增解码器插入所述解码器链表的头部。

可选的,所述插入模块450,还包括:

链接单元454,用于将所述新增解码器对应的动态链接库和所述解码器链表进行链接。

可选的,所述查找模块420,包括:

调用单元421,用于通过Java本地接口JNI调用所述native层;

第二访问单元422,用于通过所述native层声明的所述gHead访问所述Skia的所述解码器链表;

获取单元423,用于根据所述新增图片格式从所述解码器链表的头部获取所述新增解码器。

可选的,所述解码模块430,包括:

实例创建单元431,用于根据所述新增解码器创建解码器实例;

解码单元432,用于通过所述解码器实例对所述图片进行解码,得到所述图片的图片数据,所述图片数据用于构造位图Bitmap对象进行图像绘制。

综上所述,本实施例提供的图片解码装置,通过将新增解码器添加到Skia中,当需要对新增图片格式的图片进行解码时,从Skia的解码器链表中查找用于解码该图片的新增解码器,并进一步利用该解码器对图片进行解码;解决了每次移植新的图片解码器来支持新增图片格式的图片时,都需要在程序代码中新增解码器接口,灵活性差且开发效率较低的问题;达到了利用Skia中添加的新增解码器对新增图片格式的图片进行解码,避免了在程序代码中增加相应的解码器接口,从而提高添加解码器时的灵活性和开发效率。

本实施例中,通过Hook Skia的解码器链表,将新增解码器插入解码器链表中,从而完成解码器的添加,避免了对程序代码进行修改,从而提高了添加解码器的效率和灵活性。

本实施例中,不论是网络图片、本地图片还是布局文件中引用的布局图片,均可以通过Skia中的解码器对进行解码,相较于现有技术中移植的解码器使用范围更大。

本实施例中,在添加解码器阶段,利用解码器链表中的gHead头指针向解码器链表头部插入新增解码器,提高添加解码器时的灵活性;在查找解码器阶段,利用该gHead头指针遍历查找解码器链表查找匹配的解码器,提高了查找解码器的效率。

需要说明的是:上述实施例提供的图片解码装置,仅以上述各功能模块的划分进行举例说明,实际应用中,可以根据需要而将上述功能分配由不同的功能模块完成,即将Android设备的内部结构划分成不同的功能模块,以完成以上描述的全部或者部分功能。另外,上述实施例提供的图片解码装置与图片解码方法实施例属于同一构思,其具体实现过程详见方法实施例,这里不再赘述。

应当理解的是,在本文中使用的,除非上下文清楚地支持例外情况,单数形式“一个”(“a”、“an”、“the”)旨在也包括复数形式。还应当理解的是,在本文中使用的“和/或”是指包括一个或者一个以上相关联地列出的项目的任意和所有可能组合。

上述本发明实施例序号仅仅为了描述,不代表实施例的优劣。

本领域普通技术人员可以理解实现上述实施例的全部或部分步骤可以通过硬件来完成,也可以通过程序来指令相关的硬件完成,所述的程序可以存储于一种计算机可读存储介质中,上述提到的存储介质可以是只读存储器,磁盘或光盘等。

以上所述仅为本发明的较佳实施例,并不用以限制本发明,凡在本发明的精神和原则之内,所作的任何修改、等同替换、改进等,均应包含在本发明的保护范围之内。

当前第1页1 2 3 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1