守望者--AIR技术交流

标题: as 图片的缩放算法 (二次线性 和 三次卷积) [打印本页]

作者: 破晓    时间: 2015-4-7 10:32
标题: as 图片的缩放算法 (二次线性 和 三次卷积)
  1. package {
  2.         import flash.display.BitmapData;
  3.         public class ImageScaling {
  4.                
  5.                 public static var PI:Number = Math.PI;
  6.                
  7.                 public static function getA(val:uint):uint {
  8.                         return val >>> 24;
  9.                 }
  10.                
  11.                 public static function getR(val:uint):uint {
  12.                         return (val & 0x00ffffff) >>> 16;
  13.                 }
  14.                
  15.                 public static function getG(val:uint):uint {
  16.                         return (val & 0x0000ffff) >>> 8;
  17.                 }
  18.                
  19.                 public static function getB(val:uint):uint {
  20.                         return val & 0x000000ff;
  21.                 }
  22.                
  23.                 public static function getAA(val:Array):Array {
  24.                         var ret:Array = [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]];
  25.                         for (var i:uint = 0; i < 4; ++ i) {
  26.                                 for (var j:uint = 0; j < 4; ++ j) {
  27.                                         ret[ i ][ j ] = val[ i ][ j ] >>> 24;
  28.                                 }
  29.                         }
  30.                         return ret;
  31.                 }
  32.                
  33.                 public static function getRR(val:Array):Array {
  34.                         var ret:Array = [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]];
  35.                         for (var i:uint = 0; i < 4; ++ i) {
  36.                                 for (var j:uint = 0; j < 4; ++ j) {
  37.                                         ret[ i ][ j ] = (val[ i ][ j ] & 0x00ffffff) >>> 16;
  38.                                 }
  39.                         }
  40.                         return ret;
  41.                 }
  42.                
  43.                 public static function getGG(val:Array):Array {
  44.                         var ret:Array = [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]];
  45.                         for (var i:uint = 0; i < 4; ++ i) {
  46.                                 for (var j:uint = 0; j < 4; ++ j) {
  47.                                         ret[ i ][ j ] = (val[ i ][ j ] & 0x0000ffff) >>> 8;
  48.                                 }
  49.                         }
  50.                         return ret;
  51.                 }
  52.                
  53.                 public static function getBB(val:Array):Array {
  54.                         var ret:Array = [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]];
  55.                         for (var i:uint = 0; i < 4; ++ i) {
  56.                                 for (var j:uint = 0; j < 4; ++ j) {
  57.                                         ret[ i ][ j ] = (val[ i ][ j ] & 0x000000ff);
  58.                                 }
  59.                         }
  60.                         return ret;
  61.                 }
  62.                
  63.                 public static function availablePixel (bitmapData:BitmapData, x:uint, y:uint):uint {
  64.                         var flag:Boolean = true;
  65.                         if (x < 0) { x = 0; flag = false; }
  66.                         else if (x >= bitmapData.width) { x = bitmapData.width - 1; flag = false; }
  67.                         else if (y < 0) { y = 0; flag = false; }
  68.                         else if (y >= bitmapData.height) { y = bitmapData.height - 1; flag = false; }
  69.                         var ret:uint = bitmapData.getPixel32(x, y);
  70.                         if (!flag) ret = ret & 0x00ffffff;
  71.                         return ret;
  72.                 }
  73.                
  74.                
  75.                 public static function SinXDivX(x:Number):Number {
  76.                         var a:Number = -1;
  77.                         if (x < 0) x = -x;
  78.                         var x2:Number = x*x;
  79.                         var x3:Number = x2*x;
  80.                         if (x <= 1)
  81.                                 return (a + 2) * x3 - (a + 3) * x2 + 1;       
  82.                         else if (x <= 2)
  83.                                 return a * x3 - 5 * a * x2 + 8 * a * x - 4 * a;
  84.                         return 0;
  85.                 }
  86.                
  87.                 public static function getPixels(a:Array, b:Array, c:Array):uint {
  88.                         var arfa:Array = ImageScaling.getAA(b);
  89.                         var R:Array = ImageScaling.getRR(b);
  90.                         var G:Array = ImageScaling.getGG(b);
  91.                         var B:Array = ImageScaling.getBB(b);
  92.                        
  93.                         var aa:uint = ImageScaling.MatrixMutiple(a, arfa, c) << 24;
  94.                         var rr:uint = ImageScaling.MatrixMutiple(a, R, c) << 16;
  95.                         var gg:uint = ImageScaling.MatrixMutiple(a, G, c) << 8;
  96.                         var bb:uint = ImageScaling.MatrixMutiple(a, B, c);
  97.                         //trace (aa + " " + rr + " " + gg + " " + bb);
  98.                         return aa + rr + gg + bb;
  99.                 }
  100.                
  101.                 public static function border_color(Color:Number):uint {
  102.                         if (Color <= 0) return uint(0);
  103.                         if (Color >= 255) return uint(255);
  104.                         return uint(Color);
  105.                 }
  106.                
  107.                 public static function MatrixMutiple(a:Array, b:Array, c:Array):uint {
  108.                         var ret:Number = 0;
  109.                         for (var i:int = 0; i < 4; ++ i) {
  110.                                 var tmp:Number = 0;
  111.                                 for (var j:int = 0; j < 4; ++ j) {
  112.                                         tmp += a[ j ] * b[ j ][ i ];
  113.                                 }
  114.                                 ret += c[ i ] * tmp;
  115.                         }
  116.                         return border_color(ret + 0.5);
  117.                 }
  118.                
  119.                
  120.                 public static function thirdConvolution (bitmapData:BitmapData, scalingWidth:uint, scalingHeight:uint):BitmapData {
  121.                        
  122.                         var widthFactor:Number = bitmapData.width / scalingWidth;
  123.                         var heightFactor:Number = bitmapData.height / scalingHeight;
  124.                         var i:uint = 0, j:uint = 0;
  125.                         var nbd:BitmapData = new BitmapData(scalingWidth, scalingHeight, true, 0xffffffff);
  126.                         for (i = 0; i < scalingWidth; ++ i) {
  127.                                 for (j = 0; j < scalingHeight; ++ j) {
  128.                                         var tx:Number = (i + 0.5) * widthFactor - 0.5;
  129.                                         var ty:Number = (j + 0.5) * heightFactor - 0.5;
  130.                                         if (tx < 0) tx = -tx;
  131.                                         if (ty < 0) ty = -ty;
  132.                                         var x:uint = Math.floor(tx);
  133.                                         var y:uint = Math.floor(ty);
  134.                                         var u:Number = tx - x;
  135.                                         var v:Number = ty - y;
  136.                                        
  137.                                         var A:Array = [0.0, 0.0, 0.0, 0.0];
  138.                                         var B:Array = [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]];
  139.                                         var C:Array = [0.0, 0.0, 0.0, 0.0];
  140.                                        
  141.                                         for (var k:int = 0; k < 4; ++ k) {
  142.                                                 A[ k ] = ImageScaling.SinXDivX(u+1.0-k);
  143.                                                 C[ k ] = ImageScaling.SinXDivX(v+1.0-k);
  144.                                                 for (var z:int = 0; z < 4; ++ z) {
  145.                                                         B[ k ][ z ] = ImageScaling.availablePixel(bitmapData, x+k-1, y+z-1);
  146.                                                 }
  147.                                         }
  148.                                        
  149.                                         var p:uint = ImageScaling.getPixels(A, B, C);
  150.                                         nbd.setPixel32(i, j, p);
  151.                                 }
  152.                         }
  153.                        
  154.                         return nbd;
  155.                 }
  156.                
  157.                 public static function calculator(p:Array, c:Array):uint {
  158.                         return uint(p[0]*c[0]+p[1]*c[1]+p[2]*c[2]+p[3]*c[3]);
  159.                 }
  160.                
  161.                 public static function mixedPixel(p:Array, c:Array):uint {
  162.                         var aa:Array = [0, 0, 0, 0];
  163.                         var ra:Array = [0, 0, 0, 0];
  164.                         var ga:Array = [0, 0, 0, 0];
  165.                         var ba:Array = [0, 0, 0, 0];
  166.                         for (var i:uint = 0; i < 4; ++ i) {
  167.                                 aa[ i ] = ImageScaling.getA(p[ i ]);
  168.                                 ra[ i ] = ImageScaling.getR(p[ i ]);
  169.                                 ga[ i ] = ImageScaling.getG(p[ i ]);
  170.                                 ba[ i ] = ImageScaling.getB(p[ i ]);
  171.                         }
  172.                         return (ImageScaling.calculator(aa, c) << 24) + (ImageScaling.calculator(ra, c) << 16) + (ImageScaling.calculator(ga, c) << 8) + ImageScaling.calculator(ba, c);
  173.                 }
  174.                
  175.                 public static function secondLinear (bitmapData:BitmapData, scalingWidth:uint, scalingHeight:uint):BitmapData {
  176.                        
  177.                         var widthFactor:Number = bitmapData.width / scalingWidth;
  178.                         var heightFactor:Number = bitmapData.height / scalingHeight;
  179.                         var i:uint = 0, j:uint = 0;
  180.                         var nbd:BitmapData = new BitmapData(scalingWidth, scalingHeight, true, 0xffffffff);
  181.                         for (i = 0; i < scalingWidth; ++ i) {
  182.                                 for (j = 0; j < scalingHeight; ++ j) {
  183.                                         var tx:Number = i * widthFactor - 0.5;
  184.                                         var ty:Number = j * heightFactor - 0.5;
  185.                                         if (tx < 0) tx = -tx;
  186.                                         if (ty < 0) ty = -ty;
  187.                                        
  188.                                         var x:uint = Math.floor(tx);
  189.                                         var y:uint = Math.floor(ty);
  190.                                         var u:Number = tx - x;
  191.                                         var v:Number = ty - y;
  192.                                         var ti:uint = x;
  193.                                         var tj:uint = y;

  194.                                         var p0:uint = ImageScaling.availablePixel(bitmapData, x, y);
  195.                                         var p1:uint = ImageScaling.availablePixel(bitmapData, x, y+1);
  196.                                         var p2:uint = ImageScaling.availablePixel(bitmapData, x+1, y);
  197.                                         var p3:uint = ImageScaling.availablePixel(bitmapData, x+1, y+1);
  198.                                         var pa:Array = [p0, p1, p2, p3];
  199.                                        
  200.                                         var c0:Number = (1.0-u)*(1.0-v);
  201.                                         var c1:Number = (1.0-u)*v;
  202.                                         var c2:Number = u*(1.0-v);
  203.                                         var c3:Number = u*v;
  204.                                         var ca:Array = [c0, c1, c2, c3];
  205.                                        
  206.                                         nbd.setPixel32(i, j, ImageScaling.mixedPixel(pa, ca));
  207.                                 }
  208.                         }
  209.                        
  210.                         return nbd;
  211.                 }
  212.                
  213.         }
  214. }
复制代码



测试:

  1. package {
  2.        
  3.         import flash.display.Bitmap;
  4.         import flash.display.BitmapData;
  5.         import flash.display.Sprite;
  6.         import flash.geom.Rectangle;
  7.         import flash.system.ImageDecodingPolicy;
  8.         import flash.utils.ByteArray;

  9.         [SWF(width="1000", height="600", backgroundColor="#cacaca", frameRate="24")]
  10.         public class Main extends Sprite {
  11.                 [Embed(source='dog.png')]
  12.                 public static const image:Class;
  13.                 public function Main() {
  14.                         var bitmapdata:BitmapData = (new image() as Bitmap).bitmapData
  15.                         var bitmap:Bitmap = new Bitmap(showImage2(bitmapdata));
  16.                         bitmap.x = 0;
  17.                         bitmap.y = 0;
  18.                         this.addChild(bitmap);
  19.                        
  20.                         var bitmap2:Bitmap = new Bitmap(showImage1(bitmapdata));
  21.                         bitmap2.x = 300;
  22.                         bitmap2.y = 300;
  23.                         this.addChild(bitmap2);
  24.                 }
  25.                
  26.                 public static function showImage1(bitmapdata:BitmapData):BitmapData {
  27.                         return ImageScaling.secondLinear(bitmapdata, 286, 300);
  28.                 }
  29.                
  30.                 public static function showImage2(bitmapdata:BitmapData):BitmapData {
  31.                         return ImageScaling.thirdConvolution(bitmapdata, 286, 300);
  32.                 }
  33.         }
  34. }
复制代码


参考[size=14.545454025268555px]h ttp://blog.csdn.net/housisong/article/details/1452249




本文来自:http://www.cppblog.com/misschuer/archive/2012/08/07/186538.html





欢迎光临 守望者--AIR技术交流 (http://www.airmyth.com/)