3 votes

Comment puis-je mélanger les données bitmap ?

On m'a demandé de faire un programme qui prend une image, lit les données bitmap et ensuite randomise l'image.

J'ai essayé la méthode la plus simple, en divisant la "chaîne" sur chaque " " et en la mélangeant, mais l'image est corrompue, une idée sur la façon de le faire ?

Je le ferais sur cocoa, actionscript 3, js ou php.

En gros, tant que je peux l'utiliser sur un Mac, mon client est content :)

0voto

Max Points 1915

La solution en javascript pour mélanger l'image tuile par tuile : http://fiddle.jshell.net/upgradellc/53wKG/show/ éditer : 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;
            }

La solution en javascript pour mélanger tous les pixels de l'image : 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;
        }

0voto

TheDarkIn1978 Points 7794

Voici ma solution en ActionsScript 3, mais le programme est assez lent pour les grandes images, donc il y a probablement une certaine optimisation qui pourrait/devrait être faite, bien que la vitesse de traitement varie toujours en fonction de la taille de l'image.

  1. Affichez le bitmap d'origine.
  2. Lire et stocker les données bitmap (couleurs des pixels) de l'image originale dans un vecteur 2D.
  3. Aplatissez le vecteur 2D pour mélanger les données puis restaurez le vecteur 2D.
  4. Dessinez et affichez des données bitmap en utilisant les données mélangées d'un vecteur 2D.

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;
        }
    }
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X