I am trying to create a feature on a website that allows a user to upload a pngimage using javascript and then over the top of that place a new pngimage using PHP gd that has transparent circles so that the image underneath will show though. I will then hopefully use the imagecopymerge function to merge them together. It would be great if this could all be done using AJAX, without the use of saving the users picture or the PHP gd image into a database. The user will then need to be able to save the new finished combined image to their account.

The main problem I am having is how to get the PHP gd image to be shown onto the canvas that the picture is on or any other canvas.

The main page

<div class= "box2">    
<form enctype="multipart/form-data">
<h4>Step 1: Select an image to upload</h4>
<div class= "canvas">
<input type="file" id="imageLoader" name="imageLoader"/>
<canvas id="imageCanvas"></canvas>
var imageLoader = document.getElementById('imageLoader');
    imageLoader.addEventListener('change', handleImage, false);
var canvas = document.getElementById('imageCanvas');
var ctx = canvas.getContext('2d'); 
function handleImage(e){
    var reader = new FileReader();
    reader.onload = function(event){
        var img = new Image();
        img.onload = function(){
            canvas.width = img.width;
            canvas.height = img.height;
        img.src = event.target.result;
    $(".stuff3").submit(function() {
        $.post("stuff3.php", $(".stuff3").serialize() , function(data){
<form action= "stuff3.php" method= "post">
<h4>Step 2: Choose a Size</h4>
    <input type="number" placeholder="Height" name="height" min="1" max="10" step="1" />
    <input type="number" placeholder="Width" name="width" min="1" max="12" step="1" />
<button id="loginbutton" type="submit" value="Submit"> Create Size</button>

The PHP for creating the image

  $h= $_POST['height'];
  $w= $_POST['width'];    
  header('Content-type: image/png');
  $png_image = imagecreate(100*$w, 100*$h);
  $grey = imagecolorallocate($png_image, 245, 245, 245);
  $im = imagecreatetruecolor(55, 30);
  $green = imagecolorallocate($png_image, 255, 255, 255);
  imagecolortransparent($im, $green);     
  imagefilltoborder($png_image, 0, 0, $grey, $grey);
    for ($j=0;$j<=$h-1;$j++){
      for ($i=0;$i<=$w;$i++) {
          imagefilledellipse ($png_image, $x, $y, 75, 75, $green);     // circle
did you read this post stackoverflow.com/questions/13198131/… – Rachel Gallen 6 hours ago
happy i could help. Welcome to stackoverflow.. (hours of fun! .. lol) – Rachel Gallen 3 hours ago
I put my own upload.php (as a text file) in the root of my site rachelgallen.com/upload.txt - i rename images on upload. Take a look, it may be helpful. – Rachel Gallen 2 hours ago

1 Answer 1

From your question (although it's not in your tags) i presume you mean you're using html5 canvas.

There are a couple of articles online that outline how to upload onto HTML5 canvas using php with sample code that you could adapt to your needs. This article by Desmond Shaw is quite good

upload.html sample:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
<html xmlns="http://www.w3.org/1999/xhtml">
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title>Upload Canvas Data to PHP Server</title>
        <h1>Upload Canvas Data to PHP Server</h1>
        <canvas width="80" height="80" id="canvas">canvas</canvas>
        <script type="text/javascript">
            window.onload = function() {
                var canvas = document.getElementById("canvas");
                var context = canvas.getContext("2d");
                context.rect(0, 0, 80, 80);
                context.fillStyle = 'yellow';

            <input type="button" onclick="uploadEx()" value="Upload" />

        <form method="post" accept-charset="utf-8" name="form1">
            <input name="hidden_data" id='hidden_data' type="hidden"/>

            function uploadEx() {
                var canvas = document.getElementById("canvas");
                var dataURL = canvas.toDataURL("image/png");
                document.getElementById('hidden_data').value = dataURL;
                var fd = new FormData(document.forms["form1"]);

                var xhr = new XMLHttpRequest();
                xhr.open('POST', 'upload_data.php', true);

                xhr.upload.onprogress = function(e) {
                    if (e.lengthComputable) {
                        var percentComplete = (e.loaded / e.total) * 100;
                        console.log(percentComplete + '% uploaded');
                        alert('Succesfully uploaded');

                xhr.onload = function() {


upload_data.php sample:

$upload_dir = "upload/";
$img = $_POST['hidden_data'];
$img = str_replace('data:image/png;base64,', '', $img);
$img = str_replace(' ', '+', $img);
$data = base64_decode($img);
$file = $upload_dir . mktime() . ".png";
$success = file_put_contents($file, $data);
print $success ? $file : 'Unable to save the file.';

The code sample given for imagecopymerge (that you mentioned) on the php.net site is straightforward enough:

// Create image instances
$dest = imagecreatefromgif('php.gif');  //you would use imagecreatefrompng
$src = imagecreatefromgif('php.gif');

// Copy and merge
imagecopymerge($dest, $src, 10, 10, 0, 0, 100, 47, 75);
//parameters: dest image, src image, x-co-ord of dest, y coord of dest, x-co-ord of src, y coord of src, src w, src h, merge % transparency

// Output and free from memory
header('Content-Type: image/gif');


Hopefully you will have some success adapting the code in the article, and that this will assist you. Best of luck.

David Walsh has a quite a simple article on it also davidwalsh.name/convert-canvas-image – Rachel Gallen 6 hours ago
Hi thank you for your reply this is all very helpful, I was wondering if you could clarify if it is possible to create an image using PHP gd and then put that image into a HTML5 canvas using AJAX without first saving the image to a database or a folder. – Moff 4 hours ago
In the article the image is saved to a folder on the server. I don't think this step can be bypassed. Like you're gonna have to save it somewhere, especially if you need to alter and merge the image. Sorry for late reply, was offline. Am currently restarting computer and am on phone. Laptop trouble! – Rachel Gallen 3 hours ago
back online, yahoo! – Rachel Gallen 3 hours ago
if you're only displaying the image once-off (and not holding it to display in a gallery for example), you can delete the image after you're finished outputting it. No need to take up server space unnecessarily. Is this a "twibbon"-type thing? like where you put a frame around a profile pic (e.g. on facebook?) cos if it is then just delete.. (twibbon.com) – Rachel Gallen 3 hours ago