既然之前我们已经确定了创建PNG图片的最好PNG压缩程序,那么现在来让我们深入探讨JPEG压缩程序的世界,在flash程序当中,当我们尝试压缩一些图像(例如截图)时,和压缩PNG图片一样,我们有许多备选方案,但哪一种最好呢?今天这篇文章将会深入探讨各种压缩程序的性能和文件大小(占用空间)!
以下是在今天的简述中用于比较的几个压缩程序,每种压缩程序将会在它们各自正常的调节范围内设置3种不同的品质进行压缩.
- BitmapData.encode (JPEGEncoderOptions.quality=25) //flashplayer 11.3+版本内置API
- BitmapData.encode (JPEGEncoderOptions.quality=50)
- BitmapData.encode (JPEGEncoderOptions.quality=75)
- Bloddy Crypto (quality=25) //一个类库,里面包含JPEG压缩方法
- Bloddy Crypto (quality=50)
- Bloddy Crypto (quality=75)
- as3corelib (quality=25) // 同样是一个类库,里面包含JPEG压缩方法
- as3corelib (quality=50)
- as3corelib (quality=75)
每一种压缩程序将会压缩3种类型的图片:
1、在先前的PNG 压缩测试文章中使用过的 Flash Pro CS5 Icon图片
2、跟Icon 宽高一样的任意一张图片
3、跟Icon 宽高一样,使用BitmapData.noise生成了噪点的图片
测试代码如下:
package
{
import by.blooddy.crypto.image.JPEGEncoder;
import flash.display.JPEGEncoderOptions;
import com.adobe.images.JPGEncoder;
import flash.utils.ByteArray;
import flash.geom.Rectangle;
import flash.utils.getTimer;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Loader;
import flash.display.LoaderInfo;
import flash.display.Sprite;
import flash.events.Event;
import flash.net.URLRequest;
import flash.text.TextField;
public class CompressJPEGPerformance extends Sprite
{
private var tf:TextField = new TextField();
public function CompressJPEGPerformance()
{
tf.width = stage.stageWidth;
tf.height = stage.stageHeight;
addChild(tf);
load("Adobe_Flash_Professional_CS5_icon.png", onIconLoaded);
}
private function onIconLoaded(ev:Event): void
{
var bmd:BitmapData = ((ev.target as LoaderInfo).content as Bitmap).bitmapData;
test("Icon", bmd);
load("10082934002.jpg", onPhotoLoaded);
}
private function onPhotoLoaded(ev:Event): void
{
var bmd:BitmapData = ((ev.target as LoaderInfo).content as Bitmap).bitmapData;
test("Photo", bmd);
load("Adobe_Flash_Professional_CS5_icon.png", onIconLoadedAgain);
}
private function onIconLoadedAgain(ev:Event): void
{
var bmd:BitmapData = ((ev.target as LoaderInfo).content as Bitmap).bitmapData;
bmd.noise(Math.random()*int.MAX_VALUE);
test("Noise", bmd);
}
private function row(...cols): void
{
tf.appendText(cols.join(",")+"\n");
tf.scrollV = tf.maxScrollV;
}
private function load(url:String, callback:Function): void
{
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, callback);
loader.load(new URLRequest(url));
}
private function test(title:String, bmd:BitmapData): void
{
var beforeTime:int;
var afterTime:int;
var time:int;
var rect:Rectangle = new Rectangle(0, 0, bmd.width, bmd.height);
var bytes:ByteArray;
row(title);
row("Compressor,Time,Size");
bmd.getPixel(0, 0);
beforeTime = getTimer();
bytes = bmd.encode(rect, new JPEGEncoderOptions(25));
afterTime = getTimer();
time = afterTime - beforeTime;
row("BitmapData.encode (q=25)", time, bytes.length);
beforeTime = getTimer();
bytes = bmd.encode(rect, new JPEGEncoderOptions(50));
afterTime = getTimer();
time = afterTime - beforeTime;
row("BitmapData.encode (q=50)", time, bytes.length);
beforeTime = getTimer();
bytes = bmd.encode(rect, new JPEGEncoderOptions(75));
afterTime = getTimer();
time = afterTime - beforeTime;
row("BitmapData.encode (q=75)", time, bytes.length);
beforeTime = getTimer();
bytes = JPEGEncoder.encode(bmd, 25);
afterTime = getTimer();
time = afterTime - beforeTime;
row("Blooddy (q=25)", time, bytes.length);
beforeTime = getTimer();
bytes = JPEGEncoder.encode(bmd, 50);
afterTime = getTimer();
time = afterTime - beforeTime;
row("Blooddy (q=50)", time, bytes.length);
beforeTime = getTimer();
bytes = JPEGEncoder.encode(bmd, 75);
afterTime = getTimer();
time = afterTime - beforeTime;
row("Blooddy (q=75)", time, bytes.length);
beforeTime = getTimer();
bytes = new JPGEncoder(25).encode(bmd);
afterTime = getTimer();
time = afterTime - beforeTime;
row("as3corelib (q=25)", time, bytes.length);
beforeTime = getTimer();
bytes = new JPGEncoder(50).encode(bmd);
afterTime = getTimer();
time = afterTime - beforeTime;
row("as3corelib (q=50)", time, bytes.length);
beforeTime = getTimer();
bytes = new JPGEncoder(75).encode(bmd);
afterTime = getTimer();
time = afterTime - beforeTime;
row("as3corelib (q=75)", time, bytes.length);
row();
}
}
}
运行程序
下载程序
我的测试环境如下:
Flex SDK (MXMLC) 4.6.0.23201, compiling in release mode (nodebugging or verbose stack traces)
Release version of Flash Player 11.6.602.171
2.3 Ghz Intel Core i7
Mac OS X 10.8.2
这里是我测试所得的结果:
压缩程序 | 耗时 | 文件大小 |
BitmapData.encode (q=25) | 23 | 26588 |
BitmapData.encode (q=50) | 24 | 31188 |
BitmapData.encode (q=75) | 24 | 38327 |
Blooddy (q=25) | 83 | 40613 |
Blooddy (q=50) | 83 | 46948 |
Blooddy (q=75) | 84 | 56018 |
as3corelib (q=25) | 640 | 40541 |
as3corelib (q=50) | 649 | 46876 |
as3corelib (q=75) | 651 | 55946 |
压缩程序 | 耗时 | 文件大小 |
BitmapData.encode (q=25) | 31 | 65996 |
BitmapData.encode (q=50) | 35 | 129991 |
BitmapData.encode (q=75) | 35 | 159547 |
Blooddy (q=25) | 96 | 86675 |
Blooddy (q=50) | 107 | 155782 |
Blooddy (q=75) | 108 | 199564 |
as3corelib (q=25) | 734 | 86603 |
as3corelib (q=50) | 766 | 155724 |
as3corelib (q=75) | 769 | 199493 |
压缩程序 | 耗时 | 文件大小 |
BitmapData.encode (q=25) | 44 | 272445 |
BitmapData.encode (q=50) | 53 | 462318 |
BitmapData.encode (q=75) | 63 | 676571 |
Blooddy (q=25) | 141 | 507160 |
Blooddy (q=50) | 180 | 956231 |
Blooddy (q=75) | 219 | 1407526 |
as3corelib (q=25) | 860 | 507088 |
as3corelib (q=50) | 1005 | 956159 |
as3corelib (q=75) | 1128 | 1407454 |
与PNG压缩工具形成鲜明对比的是,对于JPEG 压缩程序的选择,我们能够很容易的得到结
论,BitmapData.encode方式是最快的,并且以3-4倍的大幅度领先,而使用
bitmapData.encode方式压缩的文件也是最小的,因此,如果你的目标平台是flash
player 11.3 或更高版本,那么就应该使用BitmapData.encode.否则,你将无
BitmapData.encode提供你选择,取而代之的是,你可以使用Blooddy crypto提供的方式
进行压缩,因为其在压缩性能和文件大小都排在第二位,而as3corelib中的JEEG压缩程序
是最慢的,生成的文件大小(占用空间)也是最大的,所以我们没有任何理由去使用它。
发现一个BUG吗,有疑问或者建议吗?发表评论吧!