Validation of Base64 encoded image - php

In my cakephp program, I am converting a base64 encoded image to an image and then storing it in a folder.
How can I validate this image, before conversion?
The string is like data:image/png;base64,iVBORw0KG......
(The image can be of any extension not only png.)

This answer might be useful for processing the image.
This answer might be useful for validating the image.
Code:
$data = 'data:image/png;base64,iVBORw0KG.....';
list($type, $data) = explode(';base64,', $data, 2);
$data = str_replace(' ', '+', $data);
$data = base64_decode($data);
if (imagecreatefromstring($data) == false) { echo "invalid_image"; die(); }
file_put_contents('/storage/folder/image.png', $data);
You might also want to restrict file types.
You must keep in mind that you can't simply trust any of the data sent from the client (like 'data:image/png'), so you must rely on other means (some php functions).

Related

How to convert byte array to image and save it in folder using php ?

I'm using below code
Here $data is a byte array.
$decoded_data = base64_decode($data);
$im = imagecreatefromstring($decoded_data);
if ($im !== false) {
header('Content-Type: image/png');
$image_nam = "png_".time().".png";
imagepng($im, $image_nam);
imagedestroy($im);
}
But I don't get the exact output
try this simple code for save image into directory
file_put_contents('/myfolder/imageName.jpg', base64_decode($img));
you can also try this
$base_to_php = explode(',', $base64Img);
$data = base64_decode($base_to_php[1]);
$filepath = "/path/imageName.png"; // or image.jpg
file_put_contents($filepath,$data);
I would suggest you to refer link -
This could be possible an issue with metadata present in base64 string.
As per source the problem could be due to data:image/png;base64, is included in binary string.
The metadata present in the binary string results in invalid image data when the decoded back. Can you try it by removing metadata in the function before decoding the string.
You may use function and write output to a new file.
$position_s= strpos($base64_string , "data:image/png;base64,");
substr($base64_string, 0, $position_s) . substr($base64_string, $position_s+ strlen("data:image/png;base64,");
Note: If you are preferring explode function, it would be best to set limits:
explode(',',$base64_string,2)

Get Exif image orientation from Base-64 encoded image too slow

I'm using this code to get the Exif orientation of a JPEG image from its base64 encoded data.
$exif = exif_read_data('data://image/jpeg;base64,' . $base64EncodedImageData);
$orientation = $exif['Orientation'];
However this code is slow especially when dealing with HD images. Is there any way to get the orientation faster?
It seems to be much faster when passing a actual file path instead of the base-64 encoded string, but the image is not on the disk and the base-64 encoded string is all I have.
The fact you're loading in the entire blob is why it is taking so long, so you really just need to load in the part of the image that contains the exif data.
When you give exif_read_data a file path instead of a blob, it only reads the necessary information by default. If that is simply not an option, then you may need an ugly workaround / hack.
For example, you could specify a hard-coded value:
$image = base64_encode(file_get_contents('test.jpg'));
echo strlen($image) . '<br />'; // 81684
// only read the first 30000 characters
$exif = exif_read_data('data://image/jpeg;base64,' . substr($image, 0, 30000));
echo '<pre>';
var_dump($exif);
echo '</pre>';
Or you could increment it dynamically until the appropriate size is found:
$image = base64_encode(file_get_contents('test.jpg'));
$read = '8192';
// this will produce errors, so i am suppressing them
while (!$exif = #exif_read_data('data://image/jpeg;base64,' . substr($image, 0, $read))) {
$read += $read;
}
echo '<pre>';
var_dump($exif);
echo '</pre>';
There may be a better solution but I don't know what it is. Hope that helps.

PHP: Convert base64 to image

public function addNewCategory($category_title, $strImage) {
// get the image from the base64 string.
$strImage = str_replace('data:image/png;base64,', '', $strImage);
$strImage = str_replace(' ', '+', $strImage);
$strImage = base64_decode($strImage);
// set the path name of where the image is to be stored.
$path = dirname(__FILE__).'/category_images/'.$category_title.".png";
// save the image in the path.
file_put_contents($path, $image);
// insert category and the image path into the MySQL database.
$result = mysqli_query($this->db->connect(), "INSERT INTO category(category_title, path, created_at) VALUES ('$category_title', '$path', NOW())");
if ($result) {
return mysqli_fetch_array($result);
} else {
return false;
}
}
After running this code I found out that the PNG file with the category title name is stored in the category_images directory. But it turns out that the size of the PNG file is zero, so I believe that there is a flaw in converting the base64 string into image.
Your tips for the correction will be very much appreciated.
Edited
The Base64 string here is encoded in Android with the following method.
public String getStringFromImage(Bitmap bitmap) {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] imageBytes = stream.toByteArray();
String encodedImage = Base64.encodeToString(imageBytes, Base64.DEFAULT);
return encodedImage;
}
and here is the encoded string. I got this value using Log.i() method.
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
According to the encoded string, the data:image/png;base64, is not included in front of the string. I think now this is the reason the PNG file is not properly made. What can be done here to fix this issue?
That encoded data is the contents of the image file, and data:image/png;base64, is only used if you're cramming the image data into HTML.
Putting the data into your HTML source bloats the source, slows down your initial page load, robs the browser of the ability to download large resources like images in parallel, and makes the image un-cacheable between pages. Don't do it unless you literally have no other option.
To convert the image back to a file simply:
file_put_contents('foo.png', base64_decode($str));
Or make a PHP script pretend it's an image:
header('Content-Type: image/png');
echo base64_decode($str);
Or to do the thing I just told you not to do because seriously never do this there are so many ways to not do this, I'll be super disappointed with you if this is what you take away from this answer:
printf('<img src="data:image/png;base64,%s" />', $str);

Faster way to check if remote file has changed than md5_file()

I want to check if a remote file has changed before saving it to my server.
First I've checked if the file exists before executing a comparison using md5_file between the remote file and the local file, but this is really slow. Is there a faster way to check this?
$channelName = htmlspecialchars($_GET['channel'], ENT_QUOTES);
$json_array = json_decode(file_get_contents('http://api.hitbox.tv/media/live/'.strtolower($channelName)), true);
$getImage = $json_array['livestream'][0]['channel']['user_logo_small'];
$imageURL = "http://edge.vie.hitbox.tv/$getImage";
$imagePath = str_replace("/static/img/channel/", "", $getImage);
$ImageExtension = substr( strrchr($imagePath, '.'), 1);
$imageOutput = "images/$channelName.".$ImageExtension;
if (file_exists($imageOutput)) {
if (md5_file($imageURL) != md5_file($imageOutput)) {
file_put_contents($imageOutput, file_get_contents($imageURL));
}
} else {
file_put_contents($imageOutput, file_get_contents($imageURL));
}
Maybe someone can help me out a bit or lead me into the right direction ^^
Kind regards, Kazuto
I have used Pack and Unpack function to do something similar. Was converting image and pdf file to binary rather than md5. I am not sure about performance compare to MD5 but its good to take a look at it.
http://php.net/manual/en/function.pack.php
http://php.net/manual/en/function.unpack.php

base64 decode mixed results

I have the following code in PHP, and it works for the most, fine. I am sending a image from a mobile device to this script, which decodes it into a img file and creates a file out of it on the server. I am 99.9% sure every time its a base64 encoded.
<?php
header('Access-Control-Allow-Origin: *');
header('Content-Type: image/jpeg');
$data = ($_POST['imageData']);
define('UPLOAD_DIR', 'images/');
$img = str_replace('data:image/jpeg;base64,', '', $data);
$data = base64_decode($img);
$file = UPLOAD_DIR . uniqid() . '.jpg';
file_put_contents($file, $data);
echo ('{"imgUrl" : "' . $file . '"}');
?>
This then returns the image URL back to be added to a database.
The problem is, most of the time it does decode into a .jpg file, and other times into a txt file. I cannot see why it does it, as its a little random. But I have noticed that sometimes it will come as a $_POST, and other times, $_POST is Null. So I looked at using:
$data = json_decode(file_get_contents('php://input'));
But again, it seems inconsistant. But I put a logic statement such as:
$data = ($_POST['imageData']);
if($data == NULL) {
$data = json_decode(file_get_contents('php://input'));
}
Is there any reason I should be aware of why the code works, and sometimes does not work ?
I know this question is old, but is one of the first appearance by looking at this topic. So everyone looking at this question can find a link to a proper answer right away.
You should check this PHP - get base64 img string decode and save as jpg (resulting empty image )
Also check the conditions you're using, because
if ($data === NULL)
it may be different for
if ($data == NULL)
Also, you're saving the base64 string incorrectly to an image file.
Check that link and let me know how if it helped.

Categories