How to merge two bitmaps into one bitmap and save it to local drive
I've searched a lot but nothing seems working for me. Assistance of somebody is very much appreciated in this regard. Thanks a lot. I'm new to AS3. I'm using FlashDevelop. Below is the code I used,
package {
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');
}
}
}
How to use 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);
As others have noted, Flash is forbidden from creating, altering, modifying, saving or otherwise manipulating files. There are several ways of getting this data out of flash and into a technology that has these abilities (such as PHP), or you can use the flash.filesystem package in Air (as previously noted).
Hope that helps =
= update =
Your code is problematic in that you are writing your urlRequest and then acting upon the loaded content in one function. The URL request simply hasn't had time to fire, and the rest of your function fails, because Mask2.content == undefined or null
... I'm surprised it doesn't throw an error.
Other than that, it looks like it should work.
Try this:
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
{ ...
Note that since you are doing multiple loads, you will need to check if both are loaded before acting upon the loaded content. You can do this with a simple boolean check or... whatever. You might also check out something like LoaderMax, which has built in load queueing like this.
Note also that good asset loading usually involves a try...catch statement and the handling of several events - IOErrorEvent.IO_ERROR
, for example.
= update 2 =
Okay - we're just getting into programming logic now.
This is a problem:
private function init(e:Event = null):void
{
if (loadAssets()) {
trace('merge loaded');
//...
//...
private function loadAssets():void
{...
You're essentially asking loadAssets() to a return a value, but its return type is void
, and so will absolutely fail. Besides that, the loadAssets() is only instigating the loader, and not tracking whether the load was successful.
Lets break it into a few more steps, and set up a really simple loading queue:
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;}
}
}
I haven't checked to see if this works, so it might take a little messing with, the but basic idea should work for you. There are a bunch of ways to deal with chained conditional asset loading, this is a simple example.
Hope that helps -
This might seem a bit on the nose, but you can use the merge() method of the BitmapData class to merge two bitmaps images into one. There's an example using the merge() method at those links.
As far as saving to a local disk goes, Flash Player allows access to the file system using the FileReference class. The FileReference class has the save() method, which prompts the user to browse for a location on their file system.
For Air applications, you can access the file system by using the classes in the flash.filesystem package.
精彩评论