I've created a canvas via jQuery and need to save it back to the public file directory as an image, so I can access it like any other image.

I can create the file and save it, into the same file location as my save.php script, but unable to save it to the public file directory...

var canvas = document.getElementById('myCanvas');
var dataURL = canvas.toDataURL("image/png");

  type: "POST",
  url:  Drupal.settings.basePath + "mypath/save.php",
  data: { 
     imgBase64: dataURL

Then the following php as called in save.php:

$img = $_POST['imgBase64'];
$img = str_replace('data:image/png;base64,', '', $img);
$img = str_replace(' ', '+', $img);
$fileData = base64_decode($img);
$fileName = 'public://' . uniqid() . 'myCanvas.png';
file_put_contents($fileName, $fileData);

excluding 'public://' . will happily save to the location specified in Drupal.settings.basePath + "mypath/...", but I'm unable to tell it to save to the public directory or even any directory structure...

  • That's because your script is external to Drupal. You should create it as a Drupal module, and then you will have access to the Drupal API, including the public:// stream wrapper.
    – Jaypan
    Feb 17, 2017 at 2:43
  • Thanks @Jaypan - what would I need to do to do that? I assume I'd create it as a function it the relevant module, but how would I call it in the jQuery script?
    – Simo
    Feb 17, 2017 at 2:46
  • What version of Drupal are you using?
    – Jaypan
    Feb 17, 2017 at 2:46
  • 7 (I tried moving over to 8, but too much to learn for a noob!)
    – Simo
    Feb 17, 2017 at 2:47
  • I added a reply for you that shows you how to go about it.
    – Jaypan
    Feb 17, 2017 at 3:03

1 Answer 1


You need to create a module, and define a menu path in it using hook_menu(), and the page callback for that script will be your upload script.

function hook_menu()
  $menu['mymodule/upload'] = array
    'title' => 'upload',
    'page callback' => 'mymodule_upload_callback',
    'access callback' => TRUE

  return $menu;

Note that you'll need to name your hook in line with Drupal hook naming conventions: https://www.drupal.org/docs/7/creating-custom-modules/understanding-the-hook-system-for-drupal-modules

Then your upload callback:

function mymodule_upload_callback()
  // Handle your upload here. You will have
  // access to public:// and the rest of the Drupal API.

  // call drupal_exit at the end() to prevent your
  // script from going past this point.
  • Perfect, thanks! Took a little bit of mucking around to get it all working end to end, but you're a life-saver nevertheless!
    – Simo
    Feb 17, 2017 at 3:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.