我在AS3闪存中有一个位图,我使用base64编码的jpg字符串将其发送到javascript。
一切都很好。我需要将img发送到缩小版,然后旋转180度。缩放工作,但不是旋转。轮换永远不会。我知道我显然做错了,但不知道正确的方法。
所以基本上我只需要将图像旋转180度,这样当它被发送到javascript时就会颠倒过来。
这是我的转化代码
var scaleFactor:int = 5;
var tempBitmap:BitmapData = new BitmapData(img.width/scaleFactor, img.height/scaleFactor);
var drawMatrix:Matrix = new Matrix(1/scaleFactor, 0, 0, 1 /scaleFactor );
drawMatrix.rotate(Math.PI); //180deg
tempBitmap.draw(img, drawMatrix);
答案 0 :(得分:5)
我认为你需要在旋转后翻译你的对象,否则它会被剪裁,所以你看不到它,我在舞台上使用CS5在MovieClip中做了一个带位图的例子。
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.MovieClip;
var scaleFactor:int = 1;
var tempBitmap:BitmapData = new BitmapData(img.width, img.height);
var rotationMatrix:Matrix = new Matrix();
rotationMatrix.rotate(Math.PI);
rotationMatrix.translate(img.width, img.height);
tempBitmap.draw(box_mc, rotationMatrix);
var output:Bitmap = new Bitmap(tempBitmap);
addChild(output);
我没有弄乱缩放,我猜你自己可以做到这一点。我放在舞台上的那个在右边,绘制的一个bitmapData是舞台的左上角,并正确反转。
<强>更新强>
根据下面的32bitkid评论,另请查看fl.motion.MatrixTransformer!
答案 1 :(得分:0)
/** flips individual blocks within a bitmap. Specifically used for doing sprite sheets. But I am sure you could find another use if you wanted.
* @param inBM
* @param spritePixelWidth
* @param spritePixelHeight
* @param inTransformType :An enum from TransFiveConstants. Example: TransFiveConstants.VERTICAL_FLIP
* @return a bitmap data object where all the sprites within the sprite sheet bitmap have been rotated or transformed **/
public static function makeTransformedCopyOfSpriteSheet(inSpriteSheet:BitmapData, spritePixelWidth:int, spritePixelHeight:int, inTransformType:int):BitmapData
{
//Do error check to make sure we evenly fit into the bitmap we are doing transforms on.
CONFIG::debug{
if ( (inSpriteSheet.width % spritePixelWidth ) != 0) { throw new Error("input error: width does not go in evenly! Fix it."); }
if ( (inSpriteSheet.height % spritePixelHeight) != 0) { throw new Error("input error: height does not go in evenly! Fix it."); }
}//CONFIG_debug
//Calculate width and height in sprites of the inSpriteSheet.
var widthInSprites :int = inSpriteSheet.width / spritePixelWidth ;
var heightInSprites:int = inSpriteSheet.height / spritePixelHeight;
/** Bitmap that takes rectangle chunks out of inSpriteSheet, one at a time. **/
var inBM:BitmapData = new BitmapData(spritePixelWidth, spritePixelHeight, true, 0x00);
//Inlined copy of code in makeTransformedCopy
////////////////////////////////////////////////////////////////////
var flipWidthHeight:Boolean = false;
if (inTransformType == TransFiveConstants.ROTATE_NEG_90 ||
inTransformType == TransFiveConstants.ROTATE_POS_90 )
{
flipWidthHeight = true;
}
var outWID:int = (flipWidthHeight ? inBM.height : inBM.width );
var outHGT:int = (flipWidthHeight ? inBM.width : inBM.height);
////////////////////////////////////////////////////////////////////
/** Bitmap that is a [rotated||transformed] version of inputBitmap: **/
var outBM:BitmapData = new BitmapData(outWID, outHGT, true, 0x00);
var outputSpriteSheetWidth :int = outBM.width * widthInSprites;
var outputSpriteSheetHeight:int = outBM.height * heightInSprites;
/** The output of this function **/
var outputSpriteSheet :BitmapData = new BitmapData(outputSpriteSheetWidth, outputSpriteSheetHeight, true, 0x00);
//scan through the sheet with a rectangle and make all the transformed copies you need.
//Every time you make a transformed chunk/copy, move it from the inSpriteSheet to the outputSpriteSheet
/** Places the [rotated||transformed] chunk in correct spot on outputSpriteSheet **/
var finalDestination:Point = new Point();
var cookieCutter:Rectangle = new Rectangle();
cookieCutter.width = spritePixelWidth ;
cookieCutter.height = spritePixelHeight;
for (var xx:int = 0; xx < widthInSprites ; ++xx){
for (var yy:int = 0; yy < heightInSprites; ++yy){
cookieCutter.x = xx * spritePixelWidth;
cookieCutter.y = yy * spritePixelHeight;
//Cut chunk out of main sprite sheet:
inBM.copyPixels(inSpriteSheet, cookieCutter, ZZ, null, null, true);
//Transform the chunk you cut out of the main sprite sheet:
makeTransformedCopy(inBM, inTransformType, outBM);
//Paste the transformed copy into the output sheet:
finalDestination.x = xx * outBM.width; //if outBM is rotated, this width will NOT BE SAME AS spritePixelWidth
finalDestination.y = yy * outBM.height;
outputSpriteSheet.copyPixels(outBM, outBM.rect, finalDestination, null, null, true);
}}//next [xx, yy]
return outputSpriteSheet;
}//makeTransformedCopyOfSpriteSheet
/** Flips/Mirrors and Rotates using a 1D index scan remap. "transformUsingScanRemap"
*
* Meaning, I put data into a 1D array, then change my assumptions on the "scan order" ( left-right, then top-bottom is default convention),
* I can effectively rotate or transform the pixel input.
*
* All we have to do is pack the bitmap into a 1D array. (scanning left-right, top-to-bottom)
* And then convert it BACK to the 2D array using a different formula assuming the data is packed via a different scan order.
*
* EXAMPLE:
* If we change our assumption to assume it is left-right, then BOTTOM-to-top, and make a formula for mapping 1D indexes
* to 2D values based on that scan order assumption, we achieve a vertical flip.
*
* @param inBM :Bitmap we are making a transformed copy of.
* @param inTransformType :The enum for the type of [transform||rotation] to use. For values check TransFiveConstants.as
* @param outputBitmap :Supply this to OVERWRITE an existing bitmap instead of create a NEW bitmap for output.
* @return a transformed or rotated bitmap **/
public static function makeTransformedCopy(inBM:BitmapData, inTransformType:int, outputBitmap:BitmapData = null):BitmapData
{
//If the bitmap is being ROTATED, we will have to flip the output width and height.
var flipWidthHeight:Boolean = false;
if (inTransformType == TransFiveConstants.ROTATE_NEG_90 ||
inTransformType == TransFiveConstants.ROTATE_POS_90 )
{
flipWidthHeight = true;
}
var outWID:int = (flipWidthHeight ? inBM.height : inBM.width );
var outHGT:int = (flipWidthHeight ? inBM.width : inBM.height);
//You can supply a reference to the OUTPUT of this function if you are doing some type of batch processing
//And want to avoid repetitively constructing new intermediary bitmaps:
if (outputBitmap == null)
{
var outputBitmap:BitmapData = new BitmapData(outWID, outHGT, true, 0x00);
}
else
{
if (outputBitmap.width != outWID) { ICU.error("Bad output bitmap supplied. Size is wrong."); }
if (outputBitmap.height != outHGT) { ICU.error("Bad output bitmap supplied. Size is wrong."); }
}
/** Max x index when remapping 1D values. **/
var maxXXX:int = outWID - 1;
/** Max y index when remapping 1D values. **/
var YYYmax:int = outHGT - 1;
/** Number of full columns, using 1D scan order for this orientation. **/
var fullColumns:int = 0;
/** Number of full rows, using 1D scan order for orientation specified. **/
var fullRows:int = 0;
/**What is left over after we have calculated the rows or collumns we have. **/
var remainder:int = 0;
var curPix:uint;
var index:int = ( -1);
var trans:IntPoint = new IntPoint();
inBM.lock();
outputBitmap.lock();
for (var yy:int = 0; yy < inBM.height; yy++) {
for (var xx:int = 0; xx < inBM.width ; xx++) {
++index;
//using 1D index position, remap that to correct 2D position.
//To do different transforms and rotations, simply change your assumptions on how we
//map from 1D to 2D.
//Standard 1D to 2D assumes scan lines go left-right, then top-bottom. Row by row.
//2D to 1D formula for standard:
//1D = (Y * width) + X.
//how many full widths you can get out of 1D == Y. Remainder == X.
//2D.Y = (1D/width);
//2D.X = 1D - (2D.Y * width);
if (inTransformType == TransFiveConstants.NO_TRANSFORM)
{ //[1][2] Assumed scan order (AKA 1D to 2D Mapping)
fullRows = (index / outWID); //[3][4] used to get full
remainder = index - (fullRows * outWID); //[5][6] rows and remainder.
trans.iy = fullRows;
trans.ix = remainder;
}else
if (inTransformType == TransFiveConstants.VERTICAL_FLIP)
{ //[5][6] Assumed scan order (AKA 1D to 2D Mapping)
fullRows = (index / outWID); //[3][4] used to get full
remainder = index - (fullRows * outWID); //[1][2] rows and remainder.
trans.iy = YYYmax - fullRows;
trans.ix = remainder;
}else
if (inTransformType == TransFiveConstants.ROTATE_NEG_90)
{ //[2][4][6] Assumed scan order (AKA 1D to 2D Mapping)
fullColumns = (index / outHGT); //[1][3][5] used to get full rows and remainder.
remainder = index - (fullColumns * outHGT);
trans.ix = fullColumns;
trans.iy = YYYmax - remainder;
}else
if (inTransformType == TransFiveConstants.ROTATE_POS_90)
{ //[5][3][1] Assumed scan order (AKA 1D to 2D Mapping)
fullColumns = (index / outHGT); //[6][4][2] used to get full rows and remainder.
remainder = index - (fullColumns * outHGT);
trans.ix = maxXXX - fullColumns;
trans.iy = remainder;
}else
if (inTransformType == TransFiveConstants.FLOOR_MIRROR)
{ //[2][1] Assumed scan order (AKA 1D to 2D Mapping)
fullRows = (index / outWID); //[4][3] used to get full
remainder = index - (fullRows * outWID); //[6][5] rows and remainder.
trans.iy = fullRows;
trans.ix = maxXXX - remainder;
}
else
{
throw new Error("Transform type not recognized");
}
//Copy and paste the pixel now that we know where to put it:
curPix = inBM.getPixel32(xx, yy);
outputBitmap.setPixel32(trans.ix, trans.iy, curPix);
}}//next [xx, yy]
inBM.unlock();
outputBitmap.unlock();
return outputBitmap;
}//transformUsingScanRemap