移动互联网实战--移动端音频和图形优化处理

前言:
  移动端应用, 需要省电省流量(带宽), 大资源包对用户体验是有伤害的. 因此移动端开发需要精简资源(音频/图片), 但又要保证音频/图片质量. 本文着重讲述如何优化处理资源(音频/图片), 如何在高压缩比和高质量(音质/画质)之间进行折中和权衡. 本文涉及两大块, 一块为语音处理, 另一块为图像处理.

注: 本文主要面向移动端开发者, 利用编程去优化处理. 掺杂了小编(mumuxinfei)的不成熟观点和看法, 希望能抛砖引玉.

*) 样例阐释:
1. 构造应用场景
把常规Wav格式的音频文件, 转化为更小的Mp3格式音频文件.
样例代码借助JAVE(Java Audio Video Encoder)来实现. 请点击: JAVE官网.

File source = new File("data/source.wav");
File target = new File("data/target.mp3");

// *) 设置音频属性
AudioAttributes audio = new AudioAttributes();
audio.setCodec("libmp3lame");
audio.setBitRate(new Integer(128000));
audio.setChannels(new Integer(2));
audio.setSamplingRate(new Integer(44100));

// *) 解码器设置
EncodingAttributes attrs = new EncodingAttributes();
attrs.setFormat("mp3");
attrs.setAudioAttributes(audio);

Encoder encoder = new Encoder();
encoder.encode(source, target, attrs);

2. 效果展示
Wav格式转化为Mp3格式后, 实际大小对比如下所示:

Wav格式文件: 100044byte, Mp3格式文件: 18839byte
经过小编的亲身体验(试听), 立场坚定的表示音质无明显差别, 但文件压缩比却有明显的提升.
3. 疑惑和不解
虽然大获成功, 但是小编还是有些不解, 疑问一坨坨. -_-!!!
#) 音频文件中的比特率(bitrate), 声道(channel), 采样率(samplingrate)具体是什么?
#) 在文件压缩和音质中, 那个要素扮演更重要的角色? 是他, 是她, 还是它? 唉, 我的妈呀, 小编我傻傻分不清了.
小编手溅, 于是修改下代码, 取取不同的比特率/采样率值, 看看是否有惊喜会出现?

// *) 设置音频属性
AudioAttributes audio = new AudioAttributes();
audio.setCodec("libmp3lame");
//audio.setBitRate(new Integer(128000));
audio.setBitRate(new Integer(250000));
audio.setChannels(new Integer(2));
//audio.setSamplingRate(new Integer(44100));
audio.setSamplingRate(new Integer(40000));

我乐个大擦, "惊喜"出现了, -_-!!!!!!! 居然罢工, 还抛异常, 抛,抛,抛,抛你妹啊.....

Exception in thread "main" it.sauronsoftware.jave.EncoderException: Error while opening codec for output stream #0.0 - maybe incorrect parameters such as bit_rate, rate, width or height

小编不由得困惑了, 莫非比特率和采样率有某种神秘的关系? 你看, 他两结尾都带个了‘率‘字, 而且读起来又都那么朗朗上口? 搞基不(MD, 不小心说出了心里话)? 算了, 其实小编内心还是小小期待下, oh yeah.
And 疑惑继续....
#) 比特率和采样率的取值是否有一定的限制?
#) 比特率和采样率究竟存在怎么样关系呢?

*) 基础知识
真是好奇心害死猫, 小编带着这些疑团去知(姿)识(势)渊(丰)博(富)的百度君.

小编: 百度君,你好,你能给我们介绍下音频文件中的比特率(bitrate), 声道(channel), 采样率(samplingrate)具体是什么?
百度君: #%[email protected]#$%^&*()~&(@!*^[email protected]&*^*&%(*%&^%^$~!*)()*)@&(*^@#(*^(!&(!^(

小编(怒): 讲人话......
百度君:
    音频文件有三个重要的属性描述: 采样率(samplingrate)/比特率(bitrate)/声道(channel)
    #)比特率:音频数据每秒中需要多少个比特来表示,比特率越高音频质量越好, 文件也越大.
    #)采样率:采样率定义了每秒从连续信号中提取并组成离散信号的采样个数,用赫兹(Hz)来表示.
    #)声道:声道分单声道, 双声道两种, 单声道是混合均匀从左右声道出来, 而双声道则是从不同声音
        从左右声道出来并合成, 现场立体感强.
小编(内心):哼,百度君果然吃软怕硬,不过好像说的好专业,不明觉厉.

小编:那请问比特率和采样率的取值有限定吗?
百度君:
    #) 比特率取值
    比特率取值: 32kbps/96kbps/128kbps/192kbps/224kbps/320kbps
    #) 采样率的取值
    44.1kHz系列采样: 11.025kHz, 22.05kHz, 44.1kHz, 88.2kHz, 176.4kHz
    48kHz系列采样: 12kHz, 24kHz, 48kHz, 96kHz, 192kHz
小编(内心):这下长见识了,以后叫你还抛,抛,抛不了你妹了,娃哈哈, 喂, 说你呢? 看什么看, 还看!!!!

小编:那请问,这个44.1kHz有特殊来由吗?
百度君:人类的听觉波段在20Hz到20kHz, 由Nyquist采样定理, 采样评率只要超过信号带宽2倍就不会产生混迭. 而实际上音乐CD规范则采用44.1kHz(20kHz两倍多)做为采样标准. 因此44.1kHz和人类的可听波段有一定的关联.

激动人心的时候, 终于要来了, 此时空气仿佛凝固了....

小编(喜): 那比特率君和采样率君究竟有何奸情呢? (啊呸, 竟然不小心说漏嘴了......)
百度君: 两个维度,互不影响. 简而言之, 比特率用于音频编码过程中, 而采样率用于语音播放中. 比特率与音质成正比, 文件大小成反比. 而采样率只与音质成正比.

天空一行乌鸦飞过, 哇哇哇.....

小编(内心): 这TM是玩我吗? 搞得这么亲热, 还一直形影不离, 最后竟然告诉我,他俩没半毛钱的关系, 这谁信啊!!!!!!
小编(失落): 真是个意外的结果, 万万没想到, 这个世上还是有纯粹的友谊存在, 不管你信不信, 反正我是信了.

唉, 突然觉得菊花好痒......

*) 进阶篇
1). 查阅音频文集元信息
如何借助JAVE来实现, 代码片段如下:

MultimediaInfo info = encoder.getInfo(target);
System.out.println(info);

Console 结果输出如下:

(decoder=pcm_s16le, samplingRate=22050, channels=2, bitRate=705)

评注: 解码器为: pcm_s16le, 采样率: 22.05kHz, 双声道, 比特率705Kbps
2). 尝试把Wav转化为各个比特率的Mp3格式

采样率/比特率 24kbps 48kbps 96kbps 192kbps
11.025kHz  3792 7554 15077 --
22.05kHz 3636 7241 14451 --
44.1kHz -- 7084 14137 28243

评注: 比对横向/竖向, 可以看到文件大小与比特率相关, 而采样率和比特率之间有一定的组合限定.

3). 尝试把Wa转化为各个解码器的音频格式
音频的解码器, 取决于音频格式, 简单罗列下:

mp3 => libmp3lame
ogg => vorbis
wav => pcm_s16be/pcm_s16le/pcm_s24le
3gp => libfaac

更多的解码器, 请点击: 官网 
在相同条件(比特率:24kbps, 采样率:22.05kHz, 双声道)

音频格式 mp3 ogg wav 3gp
文件大小 3636 6586 100044 2668

当在相同条件(比特率:48kbps, 采样率:44.1kHz, 双声道)

音频格式 mp3 ogg wav 3gp
文件大小 7084 8722 199980 5177

评注: 可以看出, 同等条件下文件大小: 3gp < mp3 < ogg << wav, 但文件压缩比高不代表好, 最终需要在压缩比/音质取个折中

图像处理
  移动端对图片格式的选择: 主流为PNG/JPEG格式. PNG它兼具JPG图片的质量和GIF格式的透明, 文件大小较JPEG大. JPEG格式画质好, 色彩和饱和度高, 文件相对相对较小. 因此一般有如下实践原则: 小尺寸, 色彩数小或使用到透明的时候用PNG, 大尺寸, 色彩渐变色多的时候用JPG.
  移动端的图片优化包括两方面, 一块为图片格式转换, 一块为图片像素大小调整.
代码片段:

public void convertImage(String sourceFile, String destFile, int newWidth, int newHeight) {

  // *) 假定传入destFile, 都是 *.jpg, *.png 的命名方式, 这边不做检查处理
  String format = destFile.substring(destFile.lastIndexOf(‘.‘) + 1);

  try {
    Image srcImage = ImageIO.read(new File(sourceFile));

    // *) 绘制源图像到目标图像
    BufferedImage destImage = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_3BYTE_BGR);
    Graphics2D g2 = (Graphics2D) destImage.getGraphics();
    g2.drawImage(srcImage, 0, 0, newWidth, newHeight, null);

    // *) 生成目标图像
    ImageIO.write(destImage, format, new File(destFile));
  } catch (IOException e) {
    e.printStackTrace();
  }

}

评注: 这段代码能实现jpg=>png, jpg=>gif, jpg=>bmp, png=>jpg的转换, 同时实现不同分辨率的图像转换

实验比较, 原图如下(秀福利)


文件大小比对如下:

图片格式 JPG PNG GIF BMP
文件大小 19.0KB 267.9KB 48.7KB 386.8KB

对比可以发现, 等同像素下, 图片文件大小为 jpg < gif < png < bmp

继续实验, 把大分辨率图像转化为小分辨率(主流分辨率)图像, 压缩率有多少

分辨率 1600*1200 1280*1024 1080*960 960*540 854*480
文件大小 251.7KB 188.8KB 157.7KB 90.3KB 74.7KB

如果想更深入的对图像质量进行控制, (比如jpg图像质量, 默认缺省质量为0.75):
代码片段如下:

public void convert2JPGImage(String sourceFile, String destFile, int newWidth, int newHeight, float quality) {

  FileOutputStream out = null;
  try {
    Image srcImage = ImageIO.read(new File(sourceFile));

    // *) 绘制源图像到目标图像
    BufferedImage destImage = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_3BYTE_BGR);
    Graphics2D g2 = (Graphics2D) destImage.getGraphics();
    g2.drawImage(srcImage, 0, 0, newWidth, newHeight, null);

    // *) 生成目标图像, 借助com.sun.image.codec.jpeg.JPEGImageEncoder来实现
    out = new FileOutputStream(destFile);
    JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
    JPEGEncodeParam jep = JPEGCodec.getDefaultJPEGEncodeParam(destImage);
    jep.setQuality(quality, true);
    encoder.encode(destImage, jep);
  } catch (IOException e) {
  } finally {
    if ( out != null ) {
      try {
        out.close();
      } catch (IOException e) {
      }
    }
  }

}

总结:
  移动端开发需要一定的音频/图片优化技巧, 对资源类的app而言, 这一点就特别的重要. 文件压缩比不是越高越好, 对高音质/高画质的追求会付出一定的代价.总而言之: 没有完美的解决方案, 只有永恒的折中.

移动互联网实战--移动端音频和图形优化处理

时间: 2024-10-19 22:04:25

移动互联网实战--移动端音频和图形优化处理的相关文章

移动互联网实战--资源类APP的数据存储处理和优化

前言: 对于资源类的APP, 其音频/图形占据了APP本身很大的比例. 如何存储和管理这些资源文件, 成了一个颇具挑战性的难点. 移动端的碎片化, 高中低端手机的并存, 需要开发者不光是具备基础的存储知识, 更需要基本优化的能力. 本文首先介绍手机硬件的基础, 后续会分别介绍存储方式, 资源打包, 最后以一个具体例子作结. 内容还是浅显, 望能抛砖引玉. *) 硬件基础 作为手机开发者人员, 你是否知道RAM/ROM/存储卡的区别? 而产商所宣传的运行内存, 机身内存又是什么? 1). RAM/

移动互联网实战--社交游戏的排行榜设计和实现(1)

前言: 游戏领域, 特别是移动端的社交类游戏, 排行榜成为了一种增强体验交互, 提高用户粘性的大法宝. 这边讲述在不同用户规模下, 游戏服务化/游戏平台化趋势下, 如何去设计和实现游戏排名榜. 本文侧重于传统关系型Mysql的方案实现, 后续会讲解Nosql的作用. 小编(mumuxinfei)对这块认识较浅, 所述观点不代表主流(工业界)做法, 望能抛砖引玉. 需求分析 曾几何时, 微信版飞机大战红极一时. 各路英雄刷排名, 晒成绩. 不过该排名限制在自己的好友圈中, 而每个用户的好友圈各不一

移动互联网实战--社交游戏的排行榜设计和实现(2)

前言: 游戏领域, 特别是移动端的社交类游戏, 排行榜成为了一种增强体验交互, 提高用户粘性的大法宝. 这边讲述在不同用户规模下, 游戏服务化/游戏平台化趋势下, 如何去设计和实现游戏排名榜. 本文侧重讲解Nosql在游戏排名榜中的作用. 小编(mumuxinfei)对这块认识较浅, 所述观点不代表主流(工业界)做法, 望能抛砖引玉. 秉承: 上一篇文章, 详见: 社交游戏的排行榜设计和实现(1) 进阶篇: 随着数据量/并发量的上涨, Mysql集群也呈现了一些疲态. (1). 数据库分库分表后

第31章 项目实战-PC端固定布局8

第31 章项目实战-PC 端固定布局[8]学习要点:1.归类合并2.子导航 本章主要开始使用学习用HTML5 和CSS3 来构建Web 页面,第一个项目采用PC 端固定布局来实现.一.归类合并在前面几节课中,有一部分HTML 代码比较松散,没有统一到一个类别块里.比如:很多的标签超链接没有归类到UL 里,导致一些问题等.//松散的<a>标签<a href="###">曼谷(12)</a><a href="###">东京

第31章 项目实战-PC端固定布局7

第31 章项目实战-PC 端固定布局[7]学习要点:1.侧栏制作2.详细代码 本章主要开始使用学习用HTML5 和CSS3 来构建Web 页面,第一个项目采用PC 端固定布局来实现.一.侧栏制作本节课,主要设计一下内容页面的侧栏部分,分三个小块.经过思考,侧栏会包含一些图片,而主要部分也会包含图片,那么侧栏放在左边可能会和主栏的图片冲突导致不协调,所以,我们把侧栏更换到右边.//实际上,还去掉了高度,让其自适应#container {width: 1263px;margin: 30px auto

第31章 项目实战-PC端固定布局3

第31 章项目实战-PC 端固定布局[3]学习要点:1.搜索区2.插入大图3.搜索框 本章主要开始使用学习用HTML5 和CSS3 来构建Web 页面,第一个项目采用PC 端固定布局来实现.一.搜索区本节课,我们接着header 头部往下,来设计一块搜索区.这个区域,可以是广告大图,也可以是用户注册,也可以是一个搜索条,都是一个大幅背景,内嵌一个表单.具体造型如下:从表面上来分析,就是插入一张背景大图,然后居中一个搜索条.但是,我们要求最小在1280 分辨率.最大在1920 分辨率能保持最佳的观

第31章 项目实战-PC端固定布局5

第31 章项目实战-PC 端固定布局[5]学习要点:1.底部区域2.说明区域3.版权及证件区 本章主要开始使用学习用HTML5 和CSS3 来构建Web 页面,第一个项目采用PC 端固定布局来实现.一.底部区域本节课,我们将探讨一下首页中最底部的区域.这部分区域由两个部分组成,一个是说明内容,有:合作伙伴.旅游FAQ 和联系方式,还有一个就是版权声明及各种手续证件编号.//底部区域父元素<footer id="footer">...</footer>//底部父元

第32 章项目实战-移动端流体布局3

第32 章项目实战-移动端流体布局[3]学习要点:1.搜索部分2.旅游部分3.媒体查询 本章主要开始如果通过第一个PC 端项目进行重构,设计成移动端可访问的页面,这个项目采用的是流体布局.一.搜索部分搜索部分包含三个内容,背景区块.文本框和按钮.//HTML 部分<div id="search"><input type="text" class="search" placeholder="请输入旅游景点或城市"

第32 章项目实战-移动端流体布局6

第32 章项目实战-移动端流体布局[6]学习要点:1.旅游资讯2.机票预定 本章主要开始如果通过第一个PC 端项目进行重构,设计成移动端可访问的页面,这个项目采用的是流体布局.一.旅游资讯这个如果做成移动端,那么一切从简,否则缩小时就无法容纳太多的文字.//html,布局和PC 端差不多<figure><img src="img/tour1.png" ><figcaption><hgroup><h2 class="titl