【问题标题】:How to merge two bitmaps into one bitmap and save it to local drive如何将两个位图合并为一个位图并将其保存到本地驱动器
【发布时间】:2011-09-06 04:55:18
【问题描述】:

我已经搜索了很多,但似乎没有什么对我有用。在这方面非常感谢某人的帮助。非常感谢。我是 AS3 的新手。我正在使用 FlashDevelop。下面是我使用的代码,

包装 {

import flash.display.Loader;
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.events.Event;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.BitmapDataChannel;
import flash.net.URLRequest;
import flash.events.MouseEvent;
import flash.utils.ByteArray;
import flash.net.FileReference;
import com.adobe.images.JPGEncoder;
import flash.geom.Rectangle;

public class Main extends Sprite 
{
    private var modelBmp : BitmapData;
    private var alphaBmp : BitmapData;
    private var destPoint : Point = new Point(0, 0);
    private var mask1:Loader = new Loader();
    private var mask2:Loader = new Loader();
    private var f:Bitmap;
    private var fileReference:FileReference = new FileReference();
    private var movie:MovieClip = new MovieClip();
    private var loadedimage:Bitmap;
    private var loadedimage1:Bitmap;
    public function Main():void 
    {
        if (stage) init();
        else addEventListener(Event.ADDED_TO_STAGE, init);
    }

    private function init(e:Event = null):void 
    {

        if (loadAssets()) {
            trace('merge loaded');
        modelBmp = new BitmapData(loadedimage.width, loadedimage.height);
        modelBmp.draw(loadedimage);
        alphaBmp = new BitmapData(loadedimage1.width, loadedimage1.height);
        alphaBmp.draw(loadedimage1);

        var rect:Rectangle = new Rectangle(0, 0, 200, 200);
        var pt:Point = new Point(20, 20);
        var mult:uint = 0x80; // 50% 
        modelBmp.merge(alphaBmp, rect, pt, mult, mult, mult, mult);

        var bm1:Bitmap = new Bitmap(modelBmp);
        addChild(bm1);
        bm1.x = 400;
        var bm2:Bitmap = new Bitmap(alphaBmp);
        addChild(bm2);
        bm2.x = 200;}
                }

        private function loadAssets():void
        {
        mask2.contentLoaderInfo.addEventListener(Event.COMPLETE, loadComplete1);
        mask1.contentLoaderInfo.addEventListener(Event.COMPLETE, loadComplete);
        mask2.load(new URLRequest("Photo.png"));
        mask1.load(new URLRequest("back.png"));
        trace('asset loaded');
        }

        private function loadComplete(event:Event):void 
        {
        loadedimage = Bitmap(mask1.content)
        var bitmap:BitmapData = new BitmapData(loadedimage.width, loadedimage.height, false, 0xffffffff);
        bitmap.draw(loadedimage, new Matrix())
        var image:Bitmap = new Bitmap(bitmap);
        //addChild(image);
        trace('image1 loaded');
        }

        private function loadComplete1(event:Event):void 
        {
        loadedimage1 = Bitmap(mask2.content)
        var bitmap:BitmapData = new BitmapData(loadedimage1.width, loadedimage1.height, false, 0xffffffff);
        bitmap.draw(loadedimage1, new Matrix())
        var image:Bitmap = new Bitmap(bitmap);
        //addChild(image);
        trace('image2 loaded');
        }

}

}

【问题讨论】:

  • 请详细说明合并是什么意思!另外,到目前为止,您尝试了哪些无效的方法?
  • 是的,你的问题很模糊。
  • 除了合并之外,如果您使用 AIR,您可以将 flex 中的 Bitmaps 保存到用户硬盘上的 JPEG 或 PNG 文件,或者您可以将 Bitmap 数据发送到服务器,如果你正在开发一个可以在网页上运行的 swf。
  • @silverback,看起来 Embad 想将两个影片剪辑的位图数据放在一起
  • @Eugeny89,所以它就像将 2 个位图并排放置?在这种情况下,必须做一些认真的思考:)

标签: actionscript-3 merge bitmap


【解决方案1】:

如何使用Bitmap.merge():

var bitMapData1:BitmapData = new BitmapData(100,100); //or embedded item
var bitMapData2:BitmapData = new BitmapData(100,100); // "

var bitmap:Bitmap = new Bitmap(bitMapData1);
this.addChild(bitmap);

bitmap.merge(bitMapData2, new Rectangle(0, 0, 100, 100), new Point(0, 0), 128, 128, 128, 128);

正如其他人所指出的,Flash 被禁止创建、更改、修改、保存或以其他方式操作文件。有几种方法可以将这些数据从 flash 中取出并导入具有这些功能的技术(例如 PHP),或者您可以使用 Air 中的 flash.filesystem 包(如前所述)。

希望对您有所帮助 =

= 更新 =

您的代码存在问题,因为您正在编写 urlRequest,然后在一个函数中对加载的内容进行操作。 URL 请求根本没有时间触发,并且您的其余功能失败,因为Mask2.content == undefined or null... 我很惊讶它没有抛出错误。

除此之外,它看起来应该可以工作。

试试这个:

private var _mask1:Loader; // _lowerCase naming convention

//constructor... call init()
//init.. call loadAssets()

private function loadAssets():void
{
_mask1 = new Loader(); //generally not a good idea to create objects when declaring variable
    _mask1.addEventListener(Event.COMPLETE, onCompleteFunction);
    _mask1.load(new URLRequest("Dress04.png"));

    private function onCompleteFunction(e:Event):void
    { ...

请注意,由于您正在执行多次加载,因此在对加载的内容进行操作之前,您需要检查两者是否都已加载。你可以通过一个简单的布尔检查或......来做到这一点。你也可以看看像 LoaderMax 这样的东西,它内置了这样的负载队列。

另请注意,良好的资产加载通常涉及 try...catch 语句和多个事件的处理 - 例如 IOErrorEvent.IO_ERROR

= 更新 2 =

好的 - 我们现在才进入编程逻辑。

这是一个问题:

 private function init(e:Event = null):void 
        {

            if (loadAssets()) {
                trace('merge loaded');
//...
//...
 private function loadAssets():void
        {...

您实际上是在要求 loadAssets() 返回一个值,但它的返回类型是 void,因此绝对会失败。除此之外,loadAssets() 只是在启动加载器,而不是跟踪加载是否成功。

让我们把它分成几个步骤,并设置一个非常简单的加载队列:

import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Loader;
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.events.Event;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.net.URLRequest;

    public class Main extends Sprite 
    {
        private var modelBmp    : BitmapData;
        private var alphaBmp    : BitmapData;
        private var destPoint   : Point;
        private var mask        : Loader;
        private var f           : Bitmap;
        private var movie       : MovieClip;
        private var loadedImages: Array;
        private var imageQueue      : Array;

        public function Main():void 
        {
            if (stage) init();
            else addEventListener(Event.ADDED_TO_STAGE, init);
        }

        //initialize variables
        private function init(e:Event = null):void 
        {
            //just set up a simple queue of images to load
            imageQueue      = ['Photo.png', 'back.png'];
            loadedImages    = [];

            destPoint       = new Point(0, 0);
            mask            = new Loader();
            movie           = new MovieClip();

            loadAsset( imageQueue[0] );
        }

        private function loadAsset(target:String):void
        {
            mask.contentLoaderInfo.addEventListener(Event.COMPLETE, loadComplete);  
            mask.load(new URLRequest(target));
        }

        private function loadComplete(event:Event):void 
        {
            loadedimage = Bitmap(mask.content);

            var bitmap:BitmapData = new BitmapData(loadedimage.width, loadedimage.height, false, 0xffffffff);
            bitmap.draw(loadedimage, new Matrix())
            var image:Bitmap = new Bitmap(bitmap);
            loadedImages.push(image);
            mask.unload();

            trace(imageQueue[0] + " loaded");
            imageQueue.splice( 0, 1); //remove the first index

            if (imageQueue.length > 0){
                loadAsset(imageQueue[0]);
            }else{
                mergeImages(); //if the queue is empty, then merge
            }
        }

        private function mergeImages():void
        {
            modelBmp = new BitmapData(Bitmap(loadedImages[0]).width, Bitmap(loadedImages[0]).height);
            modelBmp.draw(loadedimage);
            alphaBmp = new BitmapData(Bitmap(loadedImages[1]).width, Bitmap(loadedImages[1]).height);
            alphaBmp.draw(loadedimage1);

            var rect:Rectangle = new Rectangle(0, 0, 200, 200);
            var pt:Point = new Point(20, 20);
            var mult:uint = 0x80; // 50% 
            modelBmp.merge(alphaBmp, rect, pt, mult, mult, mult, mult);

            var bm1:Bitmap = new Bitmap(load);
            addChild(bm1);
            bm1.x = 400;
            var bm2:Bitmap = new Bitmap(alphaBmp);
            addChild(bm2);
            bm2.x = 200;}

        }

    }

我还没有检查这是否有效,所以可能需要一点点混乱,但基本的想法应该适合你。有很多方法可以处理链式条件资源加载,这是一个简单的示例。

希望有所帮助 -

【讨论】:

  • 我已经编辑了上面我使用的 AS3 代码。你们能告诉我这段代码有什么问题吗?我没有得到任何输出。非常感谢...
  • 我已按照您的建议进行了尝试,但没有得到任何输出。上面显示了更新的代码。请帮我找出这段代码现在有什么问题?非常感谢您的宝贵时间。
  • 感谢 Bosworth9。我试过你的更新。为迟到的回复道歉。它仍然没有产生任何输出。不知道问题出在哪里。无论如何,再次感谢您的帮助和时间。
  • 没有Bitmap.merge,只有BitmapData.merge
【解决方案2】:

这可能看起来有点奇怪,但是您可以使用BitmapData 类的merge() 方法将两个位图图像合并为一个。在这些链接中有一个使用 merge() 方法的示例。

就保存到本地磁盘而言,Flash Player 允许使用FileReference 类访问文件系统。 FileReference 类具有save() 方法,该方法提示用户浏览其文件系统上的位置。

对于 Air 应用程序,您可以使用 flash.filesystem 包中的类访问文件系统。

【讨论】:

  • 我已经编辑了上面我使用的 AS3 代码。你们能告诉我这段代码有什么问题吗?我没有得到任何输出。非常感谢...
猜你喜欢
  • 1970-01-01
  • 2012-10-26
  • 1970-01-01
  • 2013-03-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-05
  • 2014-04-06
相关资源
最近更新 更多