我如何改变位图数据?

时间:2013-06-20 22:38:44

标签: actionscript-3 cocoa image-processing bitmapdata

我被要求做一个拍摄图像的程序,读取位图数据然后随机化图像。

我尝试了简单的方法,在每个“”上拆分“字符串”而不是改组,但是图像变坏了,有关如何做到的任何想法?

我会在cocoa,actionscript 3,js或php上执行此操作。

基本上只要我可以在Mac上使用它,我的客户很高兴:)

2 个答案:

答案 0 :(得分:0)

javascript中的解决方案,用于按图块平铺图像图块:http://fiddle.jshell.net/upgradellc/53wKG/show/编辑:http://jsfiddle.net/upgradellc/53wKG/

  /* Script copyright Max @ www.upgradeyour.com - if it is used or modified, this message must remain intact! */
            $( document ).ready( function() {
                var imgData1 = 'img_url_or_base64';
                new ImageShuffler( imgData1, 3 );
                new ImageShuffler( imgData1, 5 );
                new ImageShuffler( imgData1, 10 );
            } );
            function ImageShuffler( imgUrl, numberOfSquares, elementToAddTo ) {
                var that = this;
                this.url = imgUrl;
                this.numberOfSquares = numberOfSquares;
                this.elementToAddTo = elementToAddTo || $( 'body' );
                this.holder = $( '<div></div>' ).appendTo( $( this.elementToAddTo ) )[0];
                this.c1 = $( '<canvas></canvas>' ).appendTo( $( this.holder ) )[0];
                this.c2 = $( '<canvas></canvas>' ).appendTo( $( this.holder ) )[0];
                this.img = $( '<img src="' + this.url + '">' ).prependTo( $( this.holder ) )[0];
                this.img.onload = function() {
                    that.doShuffleImage()
                };
            }
            ImageShuffler.prototype.doShuffleImage = function() {
                this.widthOfSquares = Math.ceil( this.img.width / this.numberOfSquares );
                this.heightOfSquares = Math.ceil( this.img.height / this.numberOfSquares );
                var extrax = (this.img.width - this.widthOfSquares * this.numberOfSquares);
                var extray = (this.img.height - this.heightOfSquares * this.numberOfSquares);
                var width = this.removeExtraPixels( this.img.width, extrax, this.widthOfSquares );
                var height = this.removeExtraPixels( this.img.height, extray, this.heightOfSquares );
                this.c1.width = this.c2.width = width;
                this.c1.height = this.c2.height = height;

                this.c1c = this.c1.getContext( '2d' );
                this.c2c = this.c2.getContext( '2d' );
                this.c1c.drawImage( this.img, 0, 0, this.img.width, this.img.height );
                var tlc = this.c1c.getImageData( this.img.width - 1, this.img.height - 1, 1, 1 ).data;
                this.c1c.fillStyle = "rgb(" + tlc[0] + "," + tlc[1] + "," + tlc[2] + ");";
                this.c1c.fillRect( 0, 0, this.c1.width, this.c1.height );
                this.c1c.drawImage( this.img, 0, 0, this.img.width, this.img.height );
                this.shuffleAll();
            };
            ImageShuffler.prototype.shuffleAll = function() {
                this.c2c.putImageData( this.c1c.getImageData( 0, 0, this.c1.width, this.c1.height ), 0, 0 );
                //this.c1c.getImageData( 0, 0, this.img.width, this.img.height );
                var timesToShuffle = Math.pow( this.numberOfSquares, 2 );
                for( var count = 0; count < timesToShuffle; count++ ) {
                    p1 = {x: rand( this.c2.width, this.widthOfSquares ), y: rand( this.c2.height, this.heightOfSquares )};
                    p2 = {x: rand( this.c2.width, this.widthOfSquares ), y: rand( this.c2.height, this.heightOfSquares )};
                    if( p1.x + this.widthOfSquares < this.c2.width ) {
                        this.swapTile( p1.x, p1.y, p2.x, p2.y );
                    }
                }
            };
            ImageShuffler.prototype.swapTile = function( x1, y1, x2, y2 ) {
                tile1 = this.c2c.getImageData( x1, y1, this.widthOfSquares, this.heightOfSquares );
                tile2 = this.c2c.getImageData( x2, y2, this.widthOfSquares, this.heightOfSquares );
                this.c2c.putImageData( tile1, x2, y2 );
                this.c2c.putImageData( tile2, x1, y1 );
            };

            ImageShuffler.prototype.removeExtraPixels = function( currentLength, extraPixels, sizeOfSquare ) {
                if( extraPixels < 0 ) {
                    return currentLength + (-1 * extraPixels);
                }
                if( extraPixels > 0 ) {
                    return currentLength + sizeOfSquare - extraPixels;
                }
                return currentLength;
            };

            //returns a random number below max which is a multiple of increment
            function rand( max, increment ) {
                return Math.floor( Math.random() * Math.ceil( max / increment ) ) * increment;
            }

javascript中用于改组图像中所有像素的解决方案: http://jsfiddle.net/upgradellc/2LJwH/1/

        /* Script copyright Max @ www.upgradeyour.com - if it is used or modified, this message must remain intact! */
        $( document ).ready( function() {
            var imgData1 = '/img/logo.png';
            new ImageShuffler( imgData1 );
        } );
        function ImageShuffler( imgUrl, elementToAddTo ) {
            var that = this;
            this.url = imgUrl;
            this.elementToAddTo = elementToAddTo || $( 'body' );
            this.holder = $( '<div></div>' ).appendTo( $( this.elementToAddTo ) )[0];
            console.log( this.holder );
            this.c1 = $( '<canvas></canvas>' ).appendTo( $( this.holder ) )[0];
            this.c2 = $( '<canvas></canvas>' ).appendTo( $( this.holder ) )[0];
            this.img = $( '<img src="' + this.url + '">' ).prependTo( $( this.holder ) )[0];
            this.img.onload = function() {
                that.doShuffleImage()
            };
        }
        ImageShuffler.prototype.doShuffleImage = function() {
            this.c1.width = this.c2.width = this.img.width;
            this.c1.height = this.c2.height = this.img.height;
            this.c1c = this.c1.getContext( '2d' );
            this.c2c = this.c2.getContext( '2d' );
            this.c1c.drawImage( this.img, 0, 0, this.img.width, this.img.height );
            this.c2c.putImageData( shuffleArray( this.c1c.getImageData( 0, 0, this.img.width, this.img.height ) ), 0, 0 );
        };

        //shuffles the data array
        function shuffleArray( arr ) {
            var length = arr.data.length;
            for( x = 0; x < length; x++ ) {
                var p1x = rand( length, 4 ), p2x = rand( length, 4 );
                var p1r = arr.data[p1x];
                var p1g = arr.data[p1x + 1];
                var p1b = arr.data[p1x + 2];
                var p1a = arr.data[p1x + 3];
                for( i = 0; i < 3; i++ ) {
                    arr.data[p2x + i] = arr.data[p1x + i];
                }
                arr.data[p2x] = p1r;
                arr.data[p2x + 1] = p1g;
                arr.data[p2x + 2] = p1b;
                arr.data[p2x + 3] = p1a;
            }
            return arr;
        }

        //returns a random number below max which is a multiple of increment
        function rand( max, increment ) {
            return Math.floor( Math.random() * Math.ceil( max / increment ) ) * increment;
        }

答案 1 :(得分:0)

这是我在ActionsScript 3中的解决方案,但程序对于大型图像来说非常慢,因此可能/应该进行一些优化,尽管处理速度仍会因图像大小而异。

  1. 显示原始位图。
  2. 读取原始图像中的位图数据(像素颜色)并将其存储到2D矢量中。
  3. 展平2D矢量以混洗数据,然后恢复2D矢量。
  4. 使用来自2D矢量的混洗数据绘制和显示位图数据。
  5. enter image description here

    package 
    {
        //Imports
        import flash.display.Bitmap;
        import flash.display.BitmapData;
        import flash.display.Sprite;
        import flash.display.StageScaleMode;
        import flash.display.StageAlign;
    
        //Class
        [SWF(width = "1150", height = "600", frameRate = "60", backgroundColor = "0x000000")]
        public class Main extends Sprite 
        {
            //Asset
            [Embed(source = "../assets/AdobeFlashLogo.png")]  // 500 x 500 pixels
            private var Image:Class;
    
            //Properties
            private var originalImage:Bitmap;
    
            //Constructor
            public function Main():void 
            {
                init();         
            }
    
            //Init
            private function init():void
            {
                stage.scaleMode = StageScaleMode.NO_SCALE;
                stage.align = StageAlign.TOP_LEFT;
    
                displayOriginalImage();
                displayShuffledImage();
            }
    
            //Display Original Image
            private function displayOriginalImage():void
            {
                originalImage = new Image() as Bitmap;          
                originalImage.x = originalImage.y = 50;
    
                addChild(originalImage);
            }
    
            //Display Shuffled Image
            private function displayShuffledImage():void
            {
                var pixelData:Vector.<Vector.<uint>> = shufflePixelData(getPixelData(originalImage));
    
                var shuffledImageData:BitmapData = new BitmapData(originalImage.width, originalImage.height);
    
                for (var i:uint = 0; i < originalImage.width; i++)
                {
                    for (var j:uint = 0; j < originalImage.height; j++)
                    {
                        shuffledImageData.setPixel32(i, j, pixelData[i][j]);
                    }
                }
    
                var shuffledImage:Bitmap = new Bitmap(shuffledImageData);
                shuffledImage.x = originalImage.x + originalImage.width + 50;
                shuffledImage.y = originalImage.y;
    
                addChild(shuffledImage);
            }
    
            //Get Pixel Data
            private function getPixelData(image:Bitmap):Vector.<Vector.<uint>>
            {
                var result:Vector.<Vector.<uint>> = new Vector.<Vector.<uint>>;
    
                for (var i:uint = 0; i < originalImage.width; i++)
                {
                    result[i] = new Vector.<uint>;
    
                    for (var j:uint = 0; j < originalImage.height; j++)
                    {
                        result[i][j] = originalImage.bitmapData.getPixel32(i, j);
                    }
                }
    
                return result;
            }
    
            //Shuffle Pixel Data
            private function shufflePixelData(pixelData:Vector.<Vector.<uint>>):Vector.<Vector.<uint>>
            {
                var i:uint;
                var j:uint;
    
                var imageWidth:uint = pixelData.length;
                var imageHeight:uint = pixelData[0].length;
    
                var flatData:Vector.<uint> = new Vector.<uint>;
    
                for (i = 0; i < imageWidth; i++)
                {
                    for (j = 0; j < imageHeight; j++)
                    {
                        flatData.push(pixelData[i][j]);
                    }
                }   
    
                var shuffledData:Vector.<uint> = new Vector.<uint>;
                var totalPixels:uint = imageWidth * imageHeight;
                var randomIndex:uint;
    
                for (i = 0; i < totalPixels; i++)
                {
                    randomIndex = Math.random() * flatData.length;
                    shuffledData.push(flatData.splice(randomIndex, 1)[0]);              
                }
    
                var result:Vector.<Vector.<uint>> = new Vector.<Vector.<uint>>
    
                for (i = 0; i < imageWidth; i++)
                {
                    result[i] = new Vector.<uint>;
    
                    for (j = 0; j < imageHeight; j++)
                    {
                        result[i][j] = shuffledData.shift();
                    }
                }
    
                return result;
            }
        }
    }