我被要求制作一个程序,该程序可以获取一张图片,读取位图数据然后随机化图片。
我尝试了简单地将“字符串”按每个“空格”进行分割并打乱顺序,但是图片会损坏。你有什么好的想法吗?
我可以使用Cocoa、ActionScript 3、JavaScript或PHP实现这个程序。
基本上只要我能在Mac上使用,我的客户就很满意 :)
我被要求制作一个程序,该程序可以获取一张图片,读取位图数据然后随机化图片。
我尝试了简单地将“字符串”按每个“空格”进行分割并打乱顺序,但是图片会损坏。你有什么好的想法吗?
我可以使用Cocoa、ActionScript 3、JavaScript或PHP实现这个程序。
基本上只要我能在Mac上使用,我的客户就很满意 :)
使用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;
}
/* 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;
}
这是我的ActionScript 3解决方案,但对于大型图像,程序运行速度相当慢,因此可能需要进行一些优化,尽管处理速度仍将根据图像大小而异。
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;
}
}
}