我正在使用位图数据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" );
}
答案 0 :(得分:3)
您有两个选择:1 - 将所有变换复制到矩阵,并将其作为第二个参数传递给draw()方法,2 - 绘制未变换的容器,而不是变换后的位图。
第二种方法显然很容易。但无论如何,我猜你应该能够从一个在senocular工具中转换对象的容器中获取transform.matrix(虽然从未使用它,所以不能共享细节)。
所以,第一个方式的示例:
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);
您可能想要动态创建容器,在其中添加主题,绘制并还原更改并处置容器。这取决于你。
答案 1 :(得分:1)
来自BitmapData.draw参考:
源显示对象不使用 它的任何应用转换 这个电话。它被视为存在 在库或文件中,没有矩阵 变换,没有颜色变换,没有 混合模式。绘制显示对象 (如影片剪辑)使用它 拥有变换属性,可以复制 它的转换属性对象 转换位图的属性 使用BitmapData的对象 对象
因此,您必须将框的transform属性复制到使用draw
命令创建的位图。
答案 2 :(得分:0)
我无法确定您的代码是否存在问题,但似乎没有...... 您是否尝试过裁剪的bitmapData创建位图?
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,你也可以尝试捕获该工具。
希望这会给你一些想法......