Why PHP cuts off base64 image? - php

I'm trying to use php to save a base64 image on my server.
But every time I run my code, I get this error:
PHP Warning: file_get_contents(data:image/gif;base64R0lGODlhPQBEAPeoAJosM//AwO/AwHVYZ/z595kzAP/s7P goOXMv8 fhw/v739/f 8PD98fH/8mJl fn/9ZWb8/PzWlwv///6wWGbImAPgTEMImIN9gUFCEm/gDALULDN8PAD6atYdCTX9gUNKlj8wZAKUsAOzZz UMAOsJAP/Z2ccMDA8PD/95eX5NWvsJCOVNQPtfX/8zM8 QePLl38MGBr8JCP zs9myn/8GBqwpAP/GxgwJCPny78lzYLgjAJ8vAP9fX/ MjMUcAN8zM/9wcM8ZGcATEL QePdZWf/29uc/P9cmJu9MTDImIN /r7 /vz8/P8VNQGNugV8AAF9fX8swMNgTAFlDOICAgPNSUnNWSMQ5MBAQEJE3QPIGAM9AQMqGcG9vb6MhJsEdGM8vLx8fH98AANIWAMuQeL8fABkTEPPQ0OM5OSYdGFl5jo Pj/ pqcsTE78wMFNGQLYmID4dGPvd3UBAQJmTkP 8vH9QUK vr8ZWSHpzcJMmILdwcLOGcHRQUHxwcK9PT9DQ0O/v70w5MLypoG8wKOuwsP/g4P/Q0IcwKEswKMl8aJ9fX2xjdOtGRs/Pz Dg4GImIP8gIH0sKEAwKKmTiKZ8aB/f39Wsl LFt8dgUE9PT5x5aHBwcP AgP WltdgYMyZfyywz78AAAAAAAD///8AAP9mZv///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA in my-file.php
I POST the base64 image via AJAX to my PHP page and this what I have in my PHP page:
$base64_string = $_POST['logo'];
$output_file = 'image.jpg';
file_put_contents('../logos/'.$output_file, file_get_contents($base64_string));
When I look inside the logos folder, I see the image.jpg being created but it has no content.
when I look at the error that PHP throws out, the base64 image seems to be a lot shorter than the actual base64 that I am POSTing!
Can someone please advice on this issue?
I also changed my server's post_max_size to 120M but I still get the same error.
EDIT:
Here's the base64 image that I am sending to my PHP page:
data:image/gif;base64,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

Of course this is not working.
It's because you try to read a file at path $base64_string.
$base64_string = $_POST['logo'];
$output_file = 'image.jpg';
file_put_contents('../logos/'.$output_file, $base64_string);
Will work.

Related

Upload image from Android app through php move_uploaded_file

I'm trying to upload image file from my android app to a server. This is my php file that is processing incoming images from my website and iOS app to be used in move_uploaded_file function:
<?php include '../../../init.php';
$post_id = $_GET['post_id'];
$image_temp = $_FILES['image']['tmp_name'];
$image_name = $_FILES['image']['name'];
$image_ext = strtolower(end(explode('.', $image_name)));
upload_page_image($image_temp, $image_ext, $post_id);
Now, in android I came up to the point when I have Base64 encoded string:
params.put("image",imageToString(bitmap));
Then, I bring this to my PHP file like this:
<$php
....
$image = base64_decode(_POST['image']);
...
But now, how do I brake it in to $_FILES['image']['temp_name'] and $_FILES['image']['name']? All the other examples I went through are using file_put_contents. I need it to be move_uploaded_files.
Any help is appreciated.
Thanks
this worked for me enter link description here
You must submit image using Multipart Form Data for use move_uploaded_files in php
Ok, that was the most difficult stuff I ever went through. The problem is that when I use php function file_put_contents(), it first makes everything easy on android app side, just convert bitmap to Base64 and pass it to php file. But... one very important thing got lost in this process.... it's that $exif['Orientation'] when using exif_read_data. This parameter is not there any more.
Now, when going back to android app and trying to get image orientation before sending the file to php, the standard function such as below:
ExifInterface exifReader = new ExifInterface(mFilePath);
exifReader.getAttributeInt(ExifInterface.TAG_ORIENTATION, -1);
.. or similar doesn't work. It always returns 0. ALWAYS
Solution came from using Glide https://github.com/bumptech/glide library and get current image orientation using:
InputStream is = getActivity().getContentResolver().openInputStream(originalUri);
int orientation = new ImageHeaderParser(is).getOrientation();
Once you get orientation, you pass image as Base64 and orientation number and then process upload and do orientation change and so on.

PHP - Possible to take a base64 encoded pdf data string and compress it?

So I have an XML file that has a base64 encoded data string for a pdf file, which just has an image taken from an iPad.
This pdf file can be excessively large, as much as 14MB with dimensions of 57"x38".
These images are taken from an iPad through a DocuSign session, thus I have no way at the moment of controlling their size or format before they get to my php listener script.
However, my script cannot work with such large files as my CRM's API file size max is 10MB, and I need a way of reducing the file size before I can upload it through my CRM's API.
Now if it was just a jpg, it would be ok as there are plenty of ways to reduce file size in PHP, but it is a PDF. I have found plenty of PHP extensions for making PDFs, but I haven't found any for reading a PDF and extracting an image from it.
So is there a way to extract the image from the PDF through PHP, or perhaps compress the pdf file?
UPDATE
I didn't think about the possibility of converting a pdf into a jpg, which apparently is easier to do with imagick. Having my server admin install it and I will see if I can make it work with my script.
UPDATE 2
So I was able to get imagick working and locally I am able to convert pdf files into jpg, and reduce file size dramatically.
However, I am running into an issue using it with my application. I get the following error from my CRM's API:
Failed to parse XML-RPC request: Invalid byte 1 of 1-byte UTF-8 sequence.
So the process is the following:
XML file has a base64 encoded data stream of the pdf file.
I decode this data
I then convert with imagick and reduce file size
I base64 encode and prep for upload
CODE
$imageBlob = base64_decode((string)$pdf->PDFBytes);
$imagick.$x = new Imagick();
$imagick.$x->readImageBlob($imageBlob);
$imagick.$x->setImageFormat('jpeg');
$imagick.$x->setImageCompressionQuality(60);
$imagick.$x->adaptiveResizeImage(1024,768,true);
$imageBlob = $imagick.$x->getImageBlob();
$PDFdata[] = base64_encode($imageBlob);
I can test the date by using the proper header and I can see the new jpeg fine, so I assume the data is properly formatted.
What I am missing?
Ok, so I figured it out.
Imagick was the way to go, and my use of it was good. I just goofed up on the file name because I wasn't using a proper dynamic variable name. Code should have looked like this:
CODE
$imageBlob = base64_decode((string)$pdf->PDFBytes);
${'imagick'.$x} = new Imagick();
${'imagick'.$x}->readImageBlob($imageBlob);
${'imagick'.$x}->setImageFormat('jpeg');
${'imagick'.$x}->setImageCompressionQuality(60);
${'imagick'.$x}->adaptiveResizeImage(1024,768,true);
$imageBlob = ${'imagick'.$x}->getImageBlob();
$PDFdata[] = base64_encode($imageBlob);
$PDFfile[] = $FormCustomField . $x . '.jpg';
So the error I was getting was because of an invalid file name, because the $x variable in the previous code was getting junk values. Now everything works fine.

How to load an image from a URL into a PHP script and encode it as a base64 string?

I want to fetch an image from a URL, basically a resizing service, and then convert it to base64 string for consumption at client side.
I use the following code,
$imagePath = "www.xyz.com/resize/view.php?image=../pictures/abc.jpg&mode=crop&size=200x200";
$image = imagecreatefromstring(file_get_contents($imagePath));
$thumb_encoded = base64_encode($image);
echo "<br>".$thumb_encoded;
The $imagePath value, when opened in a browser works fine. Image is displayed.
But when running this script, the PHP throws the following error,
PHP Warning: file_get_contents(www.xyz.com/resize/view.php?image=../../pictures/abc.jpg&\amp;mode=crop&\amp;size=200x200): failed to open stream: No such file or directory in resizeImage.php on line 12
The & params in the URL which are needed for $_GET are getting converted to &\amp; while making the request in the PHP script.
I have tried urlencode() and htmlspecialchars($url) and html_entity_decode() and also escape characters, but in vain. I get the same/similar issues.
The image wont just load, the URL which the script queries is Wrong.
Can someone point out the issue here and help me?

How to save the jpg file from base64 data

I have the base 64 data for my images and I want to save them in my local machine as JPG Files.
My base 64 code starts with
data:image/jpg;base64,/...
I already tried to save it by the following code:
file_put_contents('MyFile.jpg', base64_decode($imgData1));
But I cannot open the created image; it says "the file appears to be damaged, corrupt, or is too large". Could you please let me know what I'm missing.
Also if you need any more clarification, please let me know which part you need more clarification.
Get rid of the prefex before calling base64_decode.
<?php
// get rid of everything up to and including the last comma
$imgData1 = substr($imgData1, 1+strrpos($imgData1, ','));
// write the decoded file
file_put_contents('MyFile.jpg', base64_decode($imgData1));
This looks not just base64 but PHP stream wrapper data.
file_put_contents('MyFile.jpg', file_get_contents('data:image/jpg;base64,/...'));
You need to use imagecreatefromstring and imagejpeg, here's an example:
$imageStr = base64_decode($imgData1);
$image = imagecreatefromstring($imageStr);
imagejpeg($image, $somePath);

Uploading PNG file to nginx server via HTTP_RAW_POST_DATA results in corrupted image

I'm trying to debug this issue by posting raw PNG image data to the server with the help of Postman. Here's a screenshot, which might help to understand the issue:
On the server I'm receiving the file as follows:
$png = $GLOBALS["HTTP_RAW_POST_DATA"];
Then I write the data to a new file:
$fh = fopen($myFile, 'w') or die("can't open file");
fwrite($fh, $png);
fclose($fh);
The file gets saved correctly, but it now has a different file size,
417KB instead of 279KB which is the size of the original file.
Now of course, I can't do any image operation as none of the functions (such as getimagesize which returns bool(false)) recognizes the file as a valid image.
I have debugged this process to a point where the issue must be somewhere in the file operations, but I don't understand why the file just doesn't result in the very same file type and size as the original, when the only thing I am doing is using the same raw data.
UPDATE:
I've now compared the encodings of the original file with the uploaded one,
and the former is in ISO-8859-1 and it displays correctly, the latter is in UTF-8 and has about 138kB more in file size.
Now I've achieved to convert the file on the server to ISO-8859-1.
fwrite($fh, iconv("UTF-8", "ISO-8859-1", $png));
The resulting file does now have the same output file size (279kB),
but it is still not recognized as a PNG image, some information seems to still get lost.
UPDATE (1):
I've been able to examine the issue further and found out, that the original file is exactly 4 bytes bigger than the generated file, thus the resulting PNG seems to be corrupted.
UPDATE (2):
I'm now able to save the file and open it as a valid PNG. The following code seems to be saving the image correctly:
$input = fopen("php://input","r+");
$destination = fopen($myFile, 'w+');
stream_copy_to_stream($input, $destination);
fclose($input);
fclose($destination);
However when trying to open the file with the imagecreatefrompng function I get a 500 error. I'm now trying to figure out if it's a memory issue in PHP.
Problem might be the way you test your POST by copying the "binary" data into a text field.
If you paste the same data into a text editor you won't get a valid image file either when saving this with the png extension.
Try to build a simple form with file field to test your upload
I use nginx for uploads and haven't had a problem, but I use the standard PHP way of uploading files as per: http://www.php.net/manual/en/features.file-upload.post-method.php
I would suggest trying that.
Try using: < ?php $postdata = file_get_contents("php://input"); ?>
To get the raw data. I use it some times to get data sent from a ajax post on cake.

Categories