JPEG格式

  1. jpeg是有损压缩格式, 将像素信息用jpeg保存成文件再读取出来,其中某些像素值会有少许变化。在保存时有个质量参数可在[0,100]之间选择,参数越大图片就越保真,但图片的体积也就越大。一般情况下选择70或80就足够了。
  2. jpeg没有透明信息。
  3. jpeg比较适合用来存储相机拍出来的照片,这类图像用jpeg压缩后的体积比较小。其使用的具体算法核心是离散余弦变换、Huffman编码、算术编码等技术,有兴趣的同学可以在网上找一大堆资料,本文就不详细介绍了。

接下来要介绍一个有关jpeg非常实用的技术——
jpeg格式支持不完全读取整张图片,即可以选择读取原图、1/2、1/4、1/8大小的图片
比如5000*5000的一张大图,可以只读取将其缩小成1/8后即625*625大小的图片。 这样比先完全读取5000*5000的图像,再用算法缩小成625*625大小不知快多少倍。
如果应用需求只需要一张小图时,这种读取方式就可以大显身手了。

在c代码中读取jpeg一般是使用libjpeg, 这个库提供了不完全读取图片的功能。

给ln::LBitmap添加有关jpeg的接口,如下ReadJpeg()第三个参数fraction可取值为1,2,4,8,分别对应1/1,1/2,1/4,1/8

  1. JpegAPI

具体的实现在JpegDemo
用上面的函数进行jpeg的读取和保存的测试

  1. ```
  2. ln::LBitmap bmp;
  3. bmp.ReadBmp(L"one.bmp");
  4. unsigned char *p = bmp.Pixel(0, 0);
  5. printf("%d, %d, %d\n", p[0], p[1], p[2]);
  6. bmp.WriteJpeg(L"one.jpg", 90);
  7. ```

读取one.bmp图片,然后保存成jpeg格式,one.jpg放大后显示如下

发现左上角的颜色发生了变化,并且也影响到周围的像素,就算将上面WriteJpeg()第二个参数换成100,也还是这种效果,这是Jpeg格式无法避免的问题
但如果读取一张风景照,再保存成Jpeg,就几乎看不出有什么差别了。

android平台下实现jpeg预读

  1. BitmapFactory.Options opt = new BitmapFactory.Options();
  2. opt.inJustDecodeBounds = true;
  3. BitmapFactory.decodeFile(info.fullPath, opt); //这里仅仅只读取jpeg的大小
  4. opt.inJustDecodeBounds = false;
  5. if (opt.outWidth > opt.outHeight) {
  6. opt.inSampleSize = opt.outWidth / phSize;//hpSize是允许的图片宽高的最大值
  7. } else {
  8. opt.inSampleSize = opt.outHeight / phSize;
  9. }
  10. Bitmap b = BitmapFactory.decodeFile(info.fullPath, opt);

将BitmapFactory.Options的inJustDecodeBounds 设置为true后,就只会读取Jpeg的大小,而不会去解析像素数据。然后再设置inSampleSize后,就可以根据这个值来读取适当大小的图片,研究Android的源码后可以发现底层也是调用的libjpeg库来实现。

ios,mac

本人还没有在iOS/mac中发现如何预读jpeg的官方API。Apple对图形、图像、多媒体领域提供了丰富接口,如果这个功能真没实现就太令我惊讶了! 不过ObjectC完全兼容C,可以调用libjpeg库来实现这个功能。

.NET下仅读取jpeg的大小

下面是用c#仅仅读取jpeg宽高(没有解析像素数据), 直接用C#读取1/2,1/4,1/8还不知道如何实现

  1. FileStream stream = new FileStream(path, FileMode.Open);
  2. Image img = Image.FromStream(stream, false, false); //关键是将第三个参数设置为false
  3. Console.WriteLine("size: {0},{1}", img.Width, img.Height);

jpeg批量转化工具

用相机拍出来的原始jpeg图片是高保真质量, 所占文件体积非常大,本人写了一个批量转化的工具,可以将jpeg的质量都转化成80, 图像的宽高不变, 这时人眼几乎看不出有什么差别, 但其体积只有原来的1/3. 如果有大量的照片需要保存时, 节约的空间就很客观了。实现原理很简单, 就是读取jpeg文件, 然后再保存. 
用c#实现的,代码量非常少,在此贴出全部源码

JpegBatchConvert

Exif信息

另外jpeg文件一般有一个附属的exif信息,这个信息中有图像大小,拍摄时间,拍摄的相关参数,照片方向,图像缩略图等信息。

用相机拍出来的jpeg都会有这个信息。如果照片方向不是正立的话,在读取到像素取后,还得按exif所指明的方向将图像旋转下。mspaint程序就没有做这个处理,有些图片用picasa查看和用mspaint查看方向就不一样。当然为了简单起见,上面的LBitmap中也自动忽略了exif信息及其图像拍摄时的方向。

如果不用读取1/2,1/4,1/8的方法,也可以从exif中来读取缩略图,但这个缩略图一般很小。

说到exif,不得不说一款用perl实现的命令行工具:exiftool。几乎所有的多媒体文件(图像、音乐、视频)都可以用这个工具来查看其有关信息,当然如果不是jpeg文件就是指广义上的"exif"。在git中有已经编译好可执行文件exiftool.exe。使用方法是将这个文件放到系统路径下,然后在想查看的文件路径下执行 exiftool filename

在实现BatchJpeg工具时如果仅仅用上面实现的LBitmap来读取,保存, 将会失去exif信息, 而相片的拍摄时间等信息又很重要, 所以还得用另一个库exiv2来读取写入exif。如果用c#, 用上面的代码exif信息会自动保留下来。默默地向c#致敬。

intelJpeg库

如果在win32环境下对jpeg IO速度有很高的要求,可以使用interlJpeg库,不开源,但提供有*.h,*.lib文件。这个库可以大大提高jpg读取、保存速度。

当时分别用c#和c实现了jpeg批量转化工具, 在处理大量图片时发现c#用时居然只有c的一半。太奇怪了,按理说,c的速度比c#应该快才对啊, 而实事是c慢了这么多。 最后发现问题就在libjpeg上,用了intetJpeg后速度就和c#差不多了(猜想.NET内部也是用intelJpeg来处理jpeg)。

JPEG格式 介绍的更多相关文章

  1. 图像JPEG格式介绍

    1 JPG格式介绍 JPEG (Joint PhotographicExperts GROUP)是由国际标准组织和国际电话电报咨询委员会为静态图像所建立的第一个国际数字图像压缩标准,也是至今一直在使用 ...

  2. 图像bayer格式介绍以及bayer插值原理CFA

    1 图像bayer格式介绍 bayer格式图片是伊士曼·柯达公司科学家Bryce Bayer发明的,Bryce Bayer所发明的拜耳阵列被广泛运用数字图像. 对于彩色图像,需要采集多种最基本的颜色, ...

  3. Matlab JPEG详细介绍

    作为一个基本的图像压缩方式,JPEG 已经得到了广泛的运用,但 JPEG 相关的基本原理,却经常被忽视,或解释得很不确切.这里我们详细讨论一下 JPEG 的编码原理,并结合实例来给出一个更加感性的认识 ...

  4. 图像bayer格式介绍【转】

    本文转载自:http://www.cnblogs.com/whw19818/p/6223143.html 1 图像bayer格式介绍 bayer格式图片是伊士曼·柯达公司科学家Bryce Bayer发 ...

  5. 让阿里云的Centos,PHP组件 ImageMagick支持png和jpeg格式

    我们在Centos安装ImageMagick教程中讲述了如何安装ImageMagick,安装完毕之后发现程序并不支持png和jpeg格式的图片,但是这两种图片又是我们平时所常见的,所以我们还要进一步地 ...

  6. Mysql Binlog 三种格式介绍及分析

    一.Mysql Binlog格式介绍       Mysql binlog日志有三种格式,分别为Statement,MiXED,以及ROW! 1.Statement:每一条会修改数据的sql都会记录在 ...

  7. ecshop图片上传JPEG格式失败问题

    在根目录下找到includes文件目录,在其目录中找到cls_image.php打开并找到: $allow_file_types = '|GIF|JPG|JEPG|PNG|BMP|SWF|'; 此处J ...

  8. 嵌入式Linux基于framebuffer的jpeg格式本地LCD屏显示

    在基于Linux的视频监控采集系统中,摄像头采集到的一帧视频图像数据一般都是经过硬件自动压缩成jpeg格式的,然后再保存到摄像头设备的缓冲区.如果要把采集到的jpeg格式显示在本地LCD屏上,由于我们 ...

  9. 超图不支持JPEG格式的WMTS服务

    就目前面而言,超图不支持JPEG格式的WMTS服务,只支持PNG格式的. <本篇完>

随机推荐

  1. Flask框架学习篇(一)

    安装好Python,pip install flask安装好flask后,开始编写第一个flask程序 #包含动态路由的flask程序from flask import Flask app= Flas ...

  2. Linux 下vim命令详解

    原博文:https://www.cnblogs.com/zknublx/p/6058679.html 高级一些的编辑器,都会包含宏功能,vim当然不能缺少了,在vim中使用宏是非常方便的: :qx   ...

  3. 由于MTU设置不当导致的访问超时

    现象 工作中遇到一件怪事:搭建好服务器后(VPN服务器,创建了虚拟网卡),服务器和客户端之间响应正常且很稳定,客户端也能正常通过服务器访问外网.但是访问个别网站时可以打开文字,但是部分图片打不开(也不 ...

  4. 离线下载pytorch安装包

    1. 选择合适的安装包下载 https://anaconda.org/pytorch/repo?type=conda&label=main 2. 安装命令: conda install 安装包 ...

  5. Oracle【select from 语句】

    Oracle[select from  语句] 1.select基本功能介绍1)投影操作:结果集是源表中的部分“列”2)选择操作:结果集是源表中的部分“行”3)选择操作+投影操作:结果集是源表中的部分 ...

  6. Oracle【二维表管理:约束】

    1.简单的表创建和字段类型最简单的方式去创建表(没有添加主键之类的约束条件)[Oracle的字段类型]number:数值类型--整数类型:number(a) 总长度a--小数类型:number(a,b ...

  7. 十三,k8s集群web端管理工具dashboard部署

    目录 部署 dashboard 由于会被墙, 所以要加一步拉取镜像 正式开始安装dashboard 查看 开放访问 配置dashboard用户 1. token 令牌认证 创建一个 serviceAc ...

  8. STM32/MINI

  9. Centos下编译安装nginx

    1.安装依赖 yum install -y pcre-devel zlib-devel gcc openssl-devel gd-devel 2.下载安装包 不同版本的nginx下载地址:http:/ ...

  10. Redis03——Redis架构

    Redis架构 1.1.问题 redis是单线程,单实例,为什么并发那么多,依旧很快呢? 回答:因为调用了系统内核的epoll 1.2.Linux的早期版本 Linux有Linux kernal,我们 ...