JPEG格式 介绍
JPEG格式
- jpeg是有损压缩格式, 将像素信息用jpeg保存成文件再读取出来,其中某些像素值会有少许变化。在保存时有个质量参数可在[0,100]之间选择,参数越大图片就越保真,但图片的体积也就越大。一般情况下选择70或80就足够了。
- jpeg没有透明信息。
- 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
JpegAPI
具体的实现在JpegDemo
用上面的函数进行jpeg的读取和保存的测试

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

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

BitmapFactory.Options opt = new BitmapFactory.Options();
opt.inJustDecodeBounds = true;
BitmapFactory.decodeFile(info.fullPath, opt); //这里仅仅只读取jpeg的大小
opt.inJustDecodeBounds = false;
if (opt.outWidth > opt.outHeight) {
opt.inSampleSize = opt.outWidth / phSize;//hpSize是允许的图片宽高的最大值
} else {
opt.inSampleSize = opt.outHeight / phSize;
}
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还不知道如何实现
FileStream stream = new FileStream(path, FileMode.Open);
Image img = Image.FromStream(stream, false, false); //关键是将第三个参数设置为false
Console.WriteLine("size: {0},{1}", img.Width, img.Height);
jpeg批量转化工具
用相机拍出来的原始jpeg图片是高保真质量, 所占文件体积非常大,本人写了一个批量转化的工具,可以将jpeg的质量都转化成80, 图像的宽高不变, 这时人眼几乎看不出有什么差别, 但其体积只有原来的1/3. 如果有大量的照片需要保存时, 节约的空间就很客观了。实现原理很简单, 就是读取jpeg文件, 然后再保存.
用c#实现的,代码量非常少,在此贴出全部源码
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格式 介绍的更多相关文章
- 图像JPEG格式介绍
1 JPG格式介绍 JPEG (Joint PhotographicExperts GROUP)是由国际标准组织和国际电话电报咨询委员会为静态图像所建立的第一个国际数字图像压缩标准,也是至今一直在使用 ...
- 图像bayer格式介绍以及bayer插值原理CFA
1 图像bayer格式介绍 bayer格式图片是伊士曼·柯达公司科学家Bryce Bayer发明的,Bryce Bayer所发明的拜耳阵列被广泛运用数字图像. 对于彩色图像,需要采集多种最基本的颜色, ...
- Matlab JPEG详细介绍
作为一个基本的图像压缩方式,JPEG 已经得到了广泛的运用,但 JPEG 相关的基本原理,却经常被忽视,或解释得很不确切.这里我们详细讨论一下 JPEG 的编码原理,并结合实例来给出一个更加感性的认识 ...
- 图像bayer格式介绍【转】
本文转载自:http://www.cnblogs.com/whw19818/p/6223143.html 1 图像bayer格式介绍 bayer格式图片是伊士曼·柯达公司科学家Bryce Bayer发 ...
- 让阿里云的Centos,PHP组件 ImageMagick支持png和jpeg格式
我们在Centos安装ImageMagick教程中讲述了如何安装ImageMagick,安装完毕之后发现程序并不支持png和jpeg格式的图片,但是这两种图片又是我们平时所常见的,所以我们还要进一步地 ...
- Mysql Binlog 三种格式介绍及分析
一.Mysql Binlog格式介绍 Mysql binlog日志有三种格式,分别为Statement,MiXED,以及ROW! 1.Statement:每一条会修改数据的sql都会记录在 ...
- ecshop图片上传JPEG格式失败问题
在根目录下找到includes文件目录,在其目录中找到cls_image.php打开并找到: $allow_file_types = '|GIF|JPG|JEPG|PNG|BMP|SWF|'; 此处J ...
- 嵌入式Linux基于framebuffer的jpeg格式本地LCD屏显示
在基于Linux的视频监控采集系统中,摄像头采集到的一帧视频图像数据一般都是经过硬件自动压缩成jpeg格式的,然后再保存到摄像头设备的缓冲区.如果要把采集到的jpeg格式显示在本地LCD屏上,由于我们 ...
- 超图不支持JPEG格式的WMTS服务
就目前面而言,超图不支持JPEG格式的WMTS服务,只支持PNG格式的. <本篇完>
随机推荐
- 什么是NoSQL,为什么要使用NoSQL?
详见: https://blog.csdn.net/a909301740/article/details/80149552 https://baike.so.com/doc/5569749-57849 ...
- 查询表中列转换为json
DECLARE @sql VARCHAR(MAX) SET @sql= (SELECT (select '+'',"'+column_name+'":"''+CAST(' ...
- Linux下安装opencv with-ffmpeg解决无法读取视频的问题
1. 编译安装ffmpeg 下载源码,执行 ./configure --disable-yasm --enbale-shared --prefix=/usr/local/ffmpeg 即可. 2. 下 ...
- Nginx返回大长度的JSON数据被截断
1 添加Nginx参数,增加缓存字符串大小 head{ proxy_buffers 16 512k; //此处值代表nginx 设置 16个 512k 的块进行缓存,总共大小为16*512k prox ...
- [转] - Linux中使用alternatives切换Jdk版本
1. 准备JDK包,分别是1.7和1.8,jdk-7u79-linux-x64.tar.gz和jdk-8u161-linux-x64.gz: 2. 解压,解压后的目录结构如图所示: JDK1.7: J ...
- python3之POST请求URL
方法一:使用requests模块 import requests as rq import json def funcpost(): url = 'http://www.***.com/' # 需要请 ...
- for(auto count:counts)
c++中for(auto count : counts) 这是C++11中的语法,即:Range-based for loop.其中counts应满足:begin(counts), end(count ...
- socket 测试工具java
SocketTest.jar http://sockettest.sourceforge.net/
- 无法连接Web 的 IIE 问题
我一个解决方案里有两个项目在一块,其中一个就突然凉凉了 然后在网上找了很多,基本都是删除vs文件,在启动,幸运的是,并没什么用. 最后我用了这个: 打开Visual Studio, 右键单击网站 &g ...
- hive的事物性 transaction manager
create table lk3 (id string,nname string,grade int,goldUser int); insert into lk3 values (,, ), (,, ...