【转】JPEG 压缩程序简述

来源:互联网 发布:java scanner是什么 编辑:程序博客网 时间:2024/06/10 01:54

    既然之前我们已经确定了创建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)2326588BitmapData.encode (q=50)2431188BitmapData.encode (q=75)2438327Blooddy (q=25)8340613Blooddy (q=50)8346948Blooddy (q=75)8456018as3corelib (q=25)64040541as3corelib (q=50)64946876as3corelib (q=75)65155946

压缩程序耗时文件大小
BitmapData.encode (q=25)3165996BitmapData.encode (q=50)35129991BitmapData.encode (q=75)35159547Blooddy (q=25)9686675Blooddy (q=50)107155782Blooddy (q=75)108199564as3corelib (q=25)73486603as3corelib (q=50)766155724as3corelib (q=75)769199493

压缩程序耗时文件大小BitmapData.encode (q=25)44272445BitmapData.encode (q=50)53462318BitmapData.encode (q=75)63676571Blooddy (q=25)141507160Blooddy (q=50)180956231Blooddy (q=75)2191407526as3corelib (q=25)860507088as3corelib (q=50)1005956159as3corelib (q=75)11281407454




 

与PNG压缩工具形成鲜明对比的是,对于JPEG 压缩程序的选择,我们能够很容易的得到结

论,BitmapData.encode方式是最快的,并且以3-4倍的大幅度领先,而使用
bitmapData.encode方式压缩的文件也是最小的,因此,如果你的目标平台是flash 
player 11.3 或更高版本,那么就应该使用BitmapData.encode.否则,你将无
BitmapData.encode提供你选择,取而代之的是,你可以使用Blooddy crypto提供的方式
进行压缩,因为其在压缩性能和文件大小都排在第二位,而as3corelib中的JEEG压缩程序
是最慢的,生成的文件大小(占用空间)也是最大的,所以我们没有任何理由去使用它。
发现一个BUG吗,有疑问或者建议吗?发表评论