我本来闭关准备把程序全部写好了再一起发文,突然发现距上次发帖已经十多天了。
百度识图原理其实很简单,就是调用百度API来对你上传的一张图片进行识别,具体可以做到:把图片里面的人物标示出来(抠图)、定位人脸(聚焦)、识别物体……,总之就是很好很强大。
调用百度API分为两个部分:根据你提前申请的“API_KEY”和“SECRECT_KEY”生成一个token,再利用这个token来调用API。因此我们把百度识图功能点分为:
1、图片格式识别
2、把图片转成BASE64格式,可利用文本方式传输
3、实现http/https网站get功能
4、返回信息处理
我们知道上述功能在linux下,几乎是不需要花费什么脑子就能实现的,因为需要的库都可以直接调用,但在鸿蒙系统下,
我试图编译“code-1.0/third_party/openssl”和“code-1.0/third_party/curl”生成我所需要的库,但一直没能成功,希望直接通过调用其源文件,也一直没能成功。所以卡在上述第三步已经很长时间了,先把前两个步骤说一下吧:
一、图片格式识别
在百度AI中,可以识别的图片主要有bmp、jpg、png,因此我们在进行识别之前,需要将待识别的图片转换为上述格式,可以考虑使用特定硬件,所以图片输出格式其实是可控的,最简单当然是BMP格式,但BMP(Bitmap)采用位映射存储格式,不采用压缩,文件所占用的空间很大,传输占用资源也较多;另外PNG和JPEG格式也用的非常多,这两种格式都是压缩后的,PNG(Portable Network Graphics)是一种无损压缩的位图片形格式,它使用从LZ77派生的无损数据压缩算法,文件体积小,而且它支持alpha通道,可以设置图片透明度;
JPEG(Joint Photographic Experts Group)采用不带透明通道的0-10级压缩图片格式(11级压缩),可选择压缩比,通过损失图像质量来获得更小的体积,在网络中用得最为广泛。
在使用时,如果只是简单看后缀名,是不太够的,如何识别图片格式呢?其实非常简单,直接读取文件开始的前个字节,比如bmp格式:bmp文件头(14字节)+位图信息头(40字节)+调色板+位图数据,用编辑器打开一张BMP图片:
文件头占14个字节
1) 前2 bytes(0,1)是’BM’(windows),’BA’(os/2 bitmap array),’CI’(os/2 color icon), ‘CP’(os/2 color pointer), ‘IC’(os/2 icon), ‘PT’(os/2 pointer)
如此处是:42 4D,即ASCII码的BM
2) 接下来4个字节(2-5)说明该位图文件的大小,用字节表示。这里的48 E5 0E(高位在后)就是976,200。
3) 接下来就是2个保留位,各占2个字节,一共4个字节设置为0。
4) 接下来4个字节是:文件头开始到实际图像数据之间的字节偏移量。
图片大小(宽*高)在10h~13h和14h~17h处,即00 00 92 02和00 00 EE 01,如下图
0x292H=658D,0x1EEH=494D
又如PNG格式
前8字节的PNG文件署名域+数据块,署名域保持不变,从01字节开始ASCII就是PNG。图片的宽*高与BMP图片所在位置相同,即00 00 02 34和00 00 02 BF(高位在前,低位在后)
0x234H=564D,0x2BF=703D
JPEG图片格式组成部分:SOI(文件头)+APP0(图像识别信息)+ DQT(定义量化表)+ SOF0(图像基本信息)+ DHT(定义Huffman表) + DRI(定义重新开始间隔)+ SOS(扫描行开始)+ EOI(文件尾)
其中文件头部分FFD8就定义了文件格式。
综上,我们只需要打开文件时,读取前几个字节,就能识别出文件的格式。