2011-06-23 21 views
1

我正在使用位圖數據api來允許用戶使用其攝像頭捕獲圖像,編輯並將其保存到其硬盤。位圖數據api,從轉換後的精靈中提取

我已經成功設法使用變換矩陣來裁剪位圖數據,但問題在於應用於捕獲圖像的任何變換(使用Senocular的變換工具)並未反映在保存的圖像中。這顯然是與.draw命令有關的,但我對此感到不知所措?

如何獲取位圖數據.draw以反映應用於捕獲圖像的縮放和旋轉變換?

您可以查看應用程序:http://s46264.gridserver.com/dev/dave/pb-photo/index.html (只需點擊所拍攝的圖像,使縮放/旋轉工具) 和源/班在拉上:http://s46264.gridserver.com/dev/dave/pb-photo/pb-photo.zip

任何澄清,將不勝感激。

感謝

代碼是:

import flash.display.Bitmap; 
import flash.display.BitmapData; 
import flash.display.Sprite; 
import flash.geom.Matrix; 
import flash.net.FileReference; 
import com.adobe.images.JPGEncoder; 
import com.senocular.display.transform.*; 

// create container for captured image to apply Transform Tool to 
var box:Sprite = new Sprite(); 
addChild(box); 
box.graphics.beginFill(0xAACCDD); 
box.graphics.drawRect(-160, -120, 320, 240); // xreg, yreg, width, height (x-y = width-height/2 to set centered registration point) 
box.x = 520; 
box.y = 140; 

// create the Transform Tool 
var tool:TransformTool = new TransformTool(new ControlSetStandard()); 
addChild(tool); 

// select the box with the transform tool when clicked. 
// deselect when clicking on the stage 
box.addEventListener(MouseEvent.MOUSE_DOWN, tool.select); 
stage.addEventListener(MouseEvent.MOUSE_DOWN, tool.deselect); 

var snd:Sound = new camerasound(); //new sound instance for the "capture" button click 

var bandwidth:int = 0; // Maximum amount of bandwidth that the current outgoing video feed can use, in bytes per second. 
var quality:int = 100; // This value is 0-100 with 1 being the lowest quality. 

var cam:Camera = Camera.getCamera(); 
cam.setQuality(bandwidth, quality); 
cam.setMode(320,240,30,false); // setMode(videoWidth, videoHeight, video fps, favor area) 
var video:Video = new Video(); 
video.attachCamera(cam); 
video.x = 20; 
video.y = 20; 
addChild(video); 

var bitmapData:BitmapData = new BitmapData(video.width,video.height); 

var bitmap:Bitmap = new Bitmap(bitmapData); 
bitmap.x = -160; 
bitmap.y = -120; 
box.addChild(bitmap); 

capture_mc.buttonMode = true; 
capture_mc.addEventListener(MouseEvent.CLICK,captureImage); 

function captureImage(e:MouseEvent):void { 
    snd.play(); 
    bitmapData.draw(video); 
    save_mc.buttonMode = true; 
    save_mc.addEventListener(MouseEvent.CLICK, onSaveJPG); 
    save_mc.alpha = 1; 
} 

save_mc.alpha = .5; 

var crop:Matrix = new Matrix(); 
crop.createBox(1, 1, 0, box.x-crop_mc.x, box.y-crop_mc.y); 

function onSaveJPG(e:Event):void{ 

    var bmp:BitmapData = new BitmapData(crop_mc.width, crop_mc.height, true); 
    bmp.draw(box, crop); 

    var encoder:JPGEncoder = new JPGEncoder(100); 

    // Save the encoded byte array to a local file. 
    var f:FileReference = new FileReference(); 
    f.save(encoder.encode(bmp), "imagem.jpg"); 

} 

回答

3

有兩種選擇:1 - 將所有變換複製到矩陣,並將其作爲第二個參數傳遞給draw()方法,2 - 繪製未轉換的容器,而不是已轉換的位圖。

第二種方法顯然很簡單。但無論如何,我想你應該能夠從一個容器中獲取transform.matrix,該容器在senocular的工具中轉換對象(從未使用它,因此不能共享細節)。

因此,對於第一方式的例子:

import flash.display.Sprite; 
import flash.display.BitmapData; 
import flash.geom.Rectangle; 
import flash.geom.Matrix; 
import flash.display.Bitmap; 

// create some subject 

var test:Sprite = new Sprite(); 
test.graphics.beginFill(0); 
test.graphics.drawRect(0, 0, 100, 50); 
test.graphics.endFill(); 

// transform 

test.x = 50; 
test.y = 50; 
test.scaleX = 1.5; 
test.scaleY = 0.5; 
test.rotation = 45; 

addChild(test); 

// draw transformed subject 

// test boundaries in test's parent coordinate space 
var rect:Rectangle = test.getRect(test.parent); 
var bmp:BitmapData = new BitmapData(rect.width, rect.height, false, 0xFFFF0000); 

// copy transform matrix 
var matrix:Matrix = test.transform.matrix; 

// translate test's matrix to match it with bitmap 
matrix.translate(-rect.x, -rect.y); 

bmp.draw(test, matrix); 

// show what we've got 
var bitmap:Bitmap = new Bitmap(bmp); 
bitmap.x = 200; 
bitmap.y = 50; 
addChild(bitmap); 

第二方式的例子:

import flash.display.Sprite; 
import flash.display.BitmapData; 
import flash.geom.Rectangle; 
import flash.geom.Matrix; 
import flash.display.Bitmap; 

// create some subject 

var container:Sprite = new Sprite(); 

var test:Sprite = new Sprite(); 
test.graphics.beginFill(0); 
test.graphics.drawRect(0, 0, 100, 50); 
test.graphics.endFill(); 

// transform 

test.x = 50; 
test.y = 50; 
test.scaleX = 1.5; 
test.scaleY = 0.5; 
test.rotation = 45; 

container.x = 50; 
container.y = 50; 

addChild(container); 
container.addChild(test); 

// draw transformed subject 

// container boundaries in it's own coordinate space. 
// we assume, that container is not transformed. 
var rect:Rectangle = container.getRect(container); 
var bmp:BitmapData = new BitmapData(rect.width, rect.height, false, 0xFFFF0000); 

// translate container's matrix to match it with bitmap 
var matrix:Matrix = new Matrix(); 
matrix.translate(-rect.x, -rect.y); 

bmp.draw(container, matrix); 

// show what we've got 
var bitmap:Bitmap = new Bitmap(bmp); 
bitmap.x = 300; 
bitmap.y = 100; 
addChild(bitmap); 

您可能需要動態創建一個容器中,加入它內部的主題,繪製和恢復容器的變化和處理。隨你便。

+0

謝謝,這有很大的幫助。與由變換工具設置的註冊點有一些問題,但現在正在從已變換的對象中繪製。 – digitalpencil

0

我真的不能告訴如果有與您的代碼的問題,但它似乎並不像有... 您是否嘗試過創建位圖裁剪位圖數據?

var bmp:BitmapData = new BitmapData(crop_mc.width, crop_mc.height, true); 
bmp.draw(box, crop); 
var bitmap = new Bitmap (bmp); 
stage.addChild (bitmap); 

那個位圖是什麼樣的?

如果它仍然看起來像未修剪的版本,在我看來你的問題可能是你正在繪製錯誤的容器。您可以嘗試將「盒子」剪輯移動到另一個容器中,並在保存圖像時繪製該「外部」容器。

我不確定senocular的工具是如何工作的,但是如果「工具」存儲修改過的BitmapData,您也可以嘗試捕獲該工具。

希望這給你一些想法...

1

BitmapData.draw參考:

源顯示對象不使用 其應用的轉換爲任何該 電話。它被視爲在庫或文件中存在 ,沒有矩陣 變換,沒有顏色變換,也沒有 混合模式。通過使用其 自己的transform屬性來繪製顯示對象 (如影片剪輯),您可以複製 其變換屬性對象的 變換使用BitmapData 對象的Bitmap 對象財產。

因此,您必須將該框的transform屬性複製到使用draw命令創建的位圖。