Save chart image with open flash chart2

5k views Asked by At

I am using Open Flash Chart 2 to create some graphs. I want to be able to save an image of the graph, which OFC2 supplies some methods to accomplish this. I used the example on the OFC2 site to directly display the raw image data on the page, but that does not work in IE6, which most of our users are using (I know, I know).

I switched to using the OFC2 method, post_image to post the raw image data to the server. I use a Perl script to receive the image data, save it to a file, and I can view the image. The unfortunate part about using the post_image method is that ActionScript throws an error when saving the image: Error #2101: The String passed to URLVariables.decode() must be a URL-encoded query string containing name/value pairs.

Which apparently is a bug in Adobe - see this page. Because of this error, the post_image method does not complete successfully, so the javascript callback won't ever fire - I basically don't have a way to tell if the image was saved successfully.

So, I thought I would use the get_img_binary method of OFC2 to get the binary data of the image, and use jQuery to post the binary data to my Perl script.

I cannot figure out how to send the binary data correctly, or how to let my Perl script receive the binary data correctly, or both.

Here is my jQuery function:

    var chartObj = $("#chart_object").get(0);
    $.ajax({
        type: "POST",
        url: 'download_image.pl',
        //contentType: 'application/octet-stream',
        contentType: 'image/png',
        //processData: false,
        //data: { imgData: chartObj.get_img_binary() },
        data: chartObj.get_img_binary(),
        dataType: "text",
        success: function(data) {
            console.log( data );
        }
    });

You can see from some of my commented out lines that I have tried various contentTypes and other settings of the Ajax call.

The Ajax call is sending some data, but it doesn't appear to be binary. I think it is a base64 representation of the binary data.

Does anyone have any ideas on how to send binary data from javascript to the server?

The Perl script I have works fine for the post_image method, so I don't think the problem is there?

Thanks in advance!

2

There are 2 answers

0
BrianH On BEST ANSWER

I seem to have stumbled onto the solution.

Here is my ajax call:

var chartObj = $("#chart_object").get(0);
$.ajax({
    type: "POST",
    url: 'download_image.pl',
    contentType: 'application/octet-stream',
    processData: false,
    data: imgData,
    dataType: "text",
    success: function(data) {
        console.log( data );
    }
});

And here is my Perl snippet to process/save the image:

use CGI qw(:standard);
use MIME::Base64;

...
my $img64 = param('POSTDATA');
my $img = decode_base64( $img64 );
...
#then print $img out to a file in binary mode

I had to decode the base64 representation of the PNG file, and then save it to a file.

1
sly63 On

i've got trouble too with using IE6 and OFC2 for saving image... So here are the scripts i use (javascript + PHP)

i know it's not very beautifull but jQuery doesn't want to work in a popup created via window.open('') on my IE6 so i decided to use a "old school method" to get it...

// javascript in the page displaying the flash chart
OFC = {};
OFC.jquery = {
    name: "jQuery",
    image: function(src) { return '<img src="data:image/png;base64,' + $('#'+src)[0].get_img_binary() + '" \/>'},
    popup: function(src) {
     var img_tag = OFC.jquery.image(src);
     var img_win = window.open('', 'imagesave');
     img_win.document.write('<html><head><title>imagesave<\/title><\/head><body>'+ img_tag + '<\/body><\/html>'); 
     img_win.document.close();
    },
    popupie: function(src) {
     var img_data = "image/png;base64,"+$("#"+src)[0].get_img_binary();
     var img_win = window.open('', 'imagesave');
     with(img_win.document) {
      write('<html>');
      write('<head>');
      write('<title>imagesave<\/title>');
      write('<\/head>');
      write('<body onload="document.forms[0].submit()">');
      write('<form action="\/ofc\/base64post.php" method="post">');
      write('<input type="hidden" name="d" id="data" value="'+img_data+'" \/>');
      write('<\/form>');    
      write('<div><img src="\/ofc\/ajax-loader.gif" border="0" alt="" \/><\/div>');
      write('<div style="font-family: Verdana;">Please wait<br \/>After you can save the   image<\/div>');
      write('<\/body>');
      write('<\/html>');
     }
     img_win.document.close();
    }
}

function save_image() { // this function is automatically called
  if ($.browser.msie)
    OFC.jquery.popupie("my_chart"); // only for IE navigators
  else
    OFC.jquery.popup("my_chart"); // for the others
}

so, when we use the save_image() function (which is automaticaly called when you right clic dans select "Save Image Locally" on the flahs chart) the image of the chart is tranfered to the popup and the data (base64 binary image) are posted to a php script /ofc/base64post.php that rander the picture :

<?php
// base64post.php
$data = split(';', $_POST['d']);
$type = $data[0];
$data64 = split(',', $data[1]);
$pic = base64_decode($data64[1]);
header("Content-type: $type");
echo $pic;
?>

hope that help someone !