8

Quick version:

How do I get an image that was generated on the users browser back to the server?

The current plan is this:

  1. The Flash developer will convert the bitmap to JPEG
  2. He will then POST the JPEG to a page on the site.
  3. I'm thinking I can create a WebService which will use a StreamReader to read the post and save it as a file.

Would that work? Any existing code/samples for doing this?

I suppose we should be able to look at code for doing any file upload to ASP.NET.

JP Hellemons
  • 5,977
  • 11
  • 63
  • 128
EfficionDave
  • 2,736
  • 3
  • 31
  • 38

3 Answers3

13

In this example, I've created a Flash file with a button on the stage. When you click that button, the Flash sends the image of the button to an ASPX file which saves it out as a JPEG. As you'll see this is done by drawing the DisplayObject into a BitmapData object and as such, you can easily replace the reference to the button with anything that inherits from DisplayObject (including a movie clip that contains the canvas for a paint application etc).

I’ll walk you through the Flash element first and then the .NET backend.

Flash

To send a generated image like this from Flash to ASP.NET (or any other backend) you’re going to need a couple of 3rd party libraries. We’ll need a JPEG Encoder (which Flash doesn’t have, but recent versions of Flex do) which we can get from the AS3 Core Lib http://code.google.com/p/as3corelib/. We’ll also need a base64 encoder for sending the data over the wire. I’ll use the one from Dynamic Flash, available at http://dynamicflash.com/goodies/base64/.

Download these and extract them somewhere sensible on your hard disk (like a C:\lib folder).

I created a new AS3 Flash file and saved it as uploader.fla. I added a button component to the stage and named it btnUpload. Next I edited the ActionScript settings and added my c:\lib folder to the classpath. Then I gave the document a class name of Uploader and saved the file.

Next, I created an ActionScript file and added the following code to it:

package
{
    import flash.display.BitmapData;
    import flash.display.MovieClip;
    import flash.events.MouseEvent;
    import flash.net.URLLoader;
    import flash.net.URLRequest;
    import flash.net.URLRequestMethod;
    import flash.net.URLVariables;
    import flash.utils.ByteArray;
    import fl.controls.Button;
    import com.adobe.images.JPGEncoder;
    import com.dynamicflash.util.Base64;


    public class Uploader extends MovieClip
    {
        // Reference to the button on the stage
        public var btnUpload:Button;

        // Encoder quality
        private var _jpegQuality:int = 100;

        // Path to the upload script
        private var _uploadPath:String = "/upload.aspx";

        public function Uploader()
        {
             btnUpload.addEventListener(MouseEvent.CLICK, buttonClick);
        }

        private function buttonClick(e:MouseEvent):void
        {
            // Create a new BitmapData object the size of the upload button.
            // We're going to send the image of the button to the server.
            var image:BitmapData = new BitmapData(btnUpload.width, btnUpload.height);

            // Draw the button into the BitmapData
            image.draw(btnUpload);

            // Encode the BitmapData into a ByteArray
            var enc:JPGEncoder = new JPGEncoder(_jpegQuality);
            var bytes:ByteArray = enc.encode(image);

            // and convert the ByteArray to a Base64 encoded string
            var base64Bytes:String = Base64.encodeByteArray(bytes);

            // Add the string to a URLVariables object
            var vars:URLVariables = new URLVariables();
            vars.imageData = base64Bytes;

            // and send it over the wire via HTTP POST
            var url:URLRequest = new URLRequest(_uploadPath);
            url.data = vars;
            url.method = URLRequestMethod.POST;

            var loader:URLLoader = new URLLoader();
            loader.load(url);
        }
    }
}

I saved this file next to the FLA with the name Uploader.as.

I published the SWF into the root of my Asp.NET website. This code assumes you want to upload the jpeg with a quality of 100% and that the script which will receive the data is called upload.aspx and is located in the root of the site.

ASP.NET

In the root of my website I created a WebForm named upload.aspx. In the .aspx file, i removed all the content apart from the page directive. It’s content look like this:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="upload.aspx.cs" Inherits="upload" %>

Then in the CodeBehind, I added the following:

using System;
using System.IO;

public partial class upload : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        // Get the data from the POST array
        string data = Request.Form["imageData"];

        // Decode the bytes from the Base64 string
        byte[] bytes = Convert.FromBase64String(data);

        // Write the jpeg to disk
        string path = Server.MapPath("~/save.jpg");
        File.WriteAllBytes(path, bytes);

        // Clear the response and send a Flash variable back to the URL Loader
        Response.Clear();
        Response.ContentType = "text/plain";
        Response.Write("ok=ok");
    }
}

There are obviously hard-coded values such as the save path but from this you should be able to create whatever system you require.

Greg B
  • 14,597
  • 18
  • 87
  • 141
  • ,,, the link you provided for downloading Base64 encoder from dynamicflash.com seems to be not working i guess , could you suggest some alternative options.Thanks – Priyank Patel Mar 21 '12 at 07:35
  • @freebird Did you Google for "ActionScript Base64 encoder"? It looks like there's one built into AS3 these days... – Greg B Mar 21 '12 at 09:07
  • ,,, i downloaded it from www.sociodox.com ,,, it helped..thanks. – Priyank Patel Mar 21 '12 at 09:27
  • I am trying the same , I need to capture image from flash and send it to asp page , my flash file is on default.aspx page , so the url should be pointing to default.aspx page ??? I need to incorporate this , when you find time could you pls assist me on this.Thanks – Priyank Patel Mar 27 '12 at 07:09
  • when i click the save button it doesnot do anyhting ,, how should be the _uploadpath set if its running on localhost. – Priyank Patel Mar 27 '12 at 08:09
  • @freebird it should be the URL to the aspx file that will handle the upload. – Greg B Mar 27 '12 at 08:19
  • ya even my aspx file is Upload.aspx ,still nothing happens when i click the save button , if you want i can show my as3 code , i need some assistance thanks – Priyank Patel Mar 27 '12 at 08:23
  • @freebird How do you mean nothing happens? Have you put a `trace` call in the `onClick` of the button to see that it's firing the event? Have you looked at the events of the `URLLoader` to see if you're getting any errors? Have you used an HTTP debugger to see if the request is being made? – Greg B Mar 27 '12 at 08:31
  • sorry it was my casual approach , I did not check the folder in which I am saving the image , I checked it and now its working well , My last question to you is that , now that I get the image I could save it directly to the database as well right ???Thanks a lot for your precious time – Priyank Patel Mar 27 '12 at 08:35
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/9352/discussion-between-greg-b-and-freebird) – Greg B Mar 27 '12 at 08:44
1

If you need to manipulate the image, as long as you can get a byte[] or a Stream of the POSTed file, you can create an image of it, e.g.

MemoryStream mstr = new MemoryStream(myByteArray);
Image myImage = Image.FromStream(mstr);
JonoW
  • 14,029
  • 3
  • 33
  • 31
0

Have him post the files like a standard HTML form. You can access those files in the Page_Load event of the page he is posting to by using the following collection

Request.Files

This will return a collection of HttpPostedFiles just like what a FileUpload control does.

Peter Lange
  • 2,786
  • 2
  • 26
  • 40