Reputation: 1369
I want to use PHP in GAE to upload file image files.
Before storing, I want to convert each file to JPEG and reduce it to thumbnail quality.
Using the following code (which fully works in a normal PHP environment, less the bucket-specific adjustments), I am able to receive the uploads and determine the temporary file name and location, but getimagesize produces an error when attempting to access the CloudStorage.
$bucket = CloudStorageTools::getDefaultGoogleStorageBucketName();
$bucketPath = "gs://" . $bucket . "/" . $_SERVER["REQUEST_ID_HASH"] . "/";
$counter = 0;
foreach($_FILES["file"]["name"] as $idx => $tempFile) {
$counter++;
$sourceFile = $bucketPath . $tempFile;
syslog(LOG_DEBUG, $sourceFile);
$photoInfo = getimagesize($sourceFile);
if ($photoInfo["mime"] == "image/jpeg") {
$photoImage = imagecreatefromjpeg($sourceFile);
$valid = true;
}
elseif ($photoInfo["mime"] == "image/gif") {
$photoImage = imagecreatefromgif($sourceFile);
$valid = true;
}
elseif ($photoInfo["mime"] == "image/png") {
$photoImage = imagecreatefrompng($sourceFile);
$valid = true;
}
if (isset($valid)) {
$date = date("Y-m-d H:i:s");
$photoFolder = rtrim($photoFolder, "/") . "/";
$photoFile = "Test {$counter} {$date}.jpg";
$imageSaved = imagejpeg($photoImage, $photoFolder.$photoFile, 50);
syslog(LOG_DEBUG, "File saved is " . $imageSaved);
}
}
The first syslog entry confirms the file path and name...
gs://[myappid].appspot.com/AC3E3530/IMG_20160701_120144.jpg
The error log shows an error in attempting to open the stream, but I don't know how to address it.
PHP Warning: getimagesize(gs://[myappid].appspot.com/AC3E3530/IMG_20160701_120144.jpg): failed to open stream: "\google\appengine\ext\cloud_storage_streams\CloudStorageStreamWrapper::stream_open" call failed in /base/data/home/apps/s~[myappid]/v1.394746390020376247/code/server.php on line 169
I already have a variation of this functionality working on GAE with photos that my server receives through Twilio (where processPhoto() is a function identical to the code I excerpted above). In this case, I'm using getimagesize and imagecreate with a URL. I just don't know how to do the same with CloudStorage.
if ($fetch && $numMedia > 0) {
for ($x = 0; $x < $numMedia; $x++) {
$sourceFile = $_REQUEST["MediaUrl" . $x];
$sid = $_REQUEST["MessageSid"];
processPhoto("sms", $projectID, $sourceFile, $caption, $sid, $mobile, $message);
}
}
Upvotes: 0
Views: 633
Reputation: 1369
I think the problem was that the temporary file was removed before I could process it. So, I...
This is the form that I generate in PHP. There's no Submit button because I watch for a file change with jQuery.
<form id='form_uploadPhotos' method='post' enctype='multipart/form-data' action='{$websiteURL}?action=uploadPhotos'>
<input type='file' id='input_uploadPhoto' name='file'>
<input type='hidden' name='projectID' value='{$projectID}'>
</form>
This is the uploadPhotos function that's called when the form is submitted:
if ($action == "uploadPhotos") {
$projectID = preg_replace("/\D/", "", $_REQUEST["projectID"]);
$bucket = CloudStorageTools::getDefaultGoogleStorageBucketName();
$bucketPath = "gs://" . $bucket . "/" . $_SERVER["REQUEST_ID_HASH"] . "/";
$date = date("Y-m-d H:i:s");
$time = time();
$photoFile = sprintf("%08d", $projectID) . "." . $date . "." . $time . ".TEMP";
$sourceFile = $photoFolder.$photoFile; // The default photo folder is defined elsewhere.
move_uploaded_file($_FILES["file"]["tmp_name"], $sourceFile);
processPhoto("upload", $projectID, $sourceFile, null, null, null, null);
}
This is the function that processes the photo. It's called by other processes that also receive photos (e.g., SMS attachments via Twilio).
function processPhoto($via, $projectID, $sourceFile, $caption, $twilioMessageID, $smsMobile, $smsMessage) {
global $photoFolder;
$photoInfo = getimagesize($sourceFile);
if ($photoInfo["mime"] == "image/jpeg") {
$photoImage = imagecreatefromjpeg($sourceFile);
$valid = true;
}
elseif ($photoInfo["mime"] == "image/gif") {
$photoImage = imagecreatefromgif($sourceFile);
$valid = true;
}
elseif ($photoInfo["mime"] == "image/png") {
$photoImage = imagecreatefrompng($sourceFile);
$valid = true;
}
if (isset($valid)) {
$date = date("Y-m-d H:i:s");
$time = time();
$photoFile = sprintf("%08d", $projectID) . "." . $date . "." . $time . ".JPEG";
$photoImage = imagecreatefromjpeg($sourceFile);
list($width, $height) = getimagesize($sourceFile);
if (max($width, $height) > 800) {
$scale = 800/max($width, $height);
$newWidth = floor($width * $scale);
$newHeight = floor($height * $scale);
$saveImage = imagecreatetruecolor($newWidth, $newHeight);
imagecopyresampled($saveImage, $photoImage, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);
}
$imageSaved = imagejpeg($photoImage, $photoFolder.$photoFile);
imagedestroy($photoImage);
if ($imageSaved) {
if (isset($twilioMessageID)) {
$twilioMediaID = substr($sourceFile, strrpos($sourceFile, "/") + 1);
purgeTwilioMedia($twilioMessageID, $twilioMediaID);
}
elseif (substr($sourceFile, strrpos($sourceFile, ".")) == ".TEMP") {
unlink($sourceFile);
}
<Additional processing (e.g., adding entry to database.)
.
.
.
}
}
}
Note: The image scaling code between "list($width, $height..." and "imagecopyresampled..." is based on Dano's answer to another question.
Upvotes: 2
Reputation: 3493
I'm guessing that you're hitting a limitation of the Standard Environment where the getimagesize
native function in the Standard runtime doesn't work with file extensions like gs://
URLs.
Upvotes: 0