Im trying to get a image from a PUT request for update a user picture(using postman), and make it pass through a validation in Laravel 5.2, for making the call in postman use the following url:
http://localhost:8000/api/v1/users?_method=PUT
and send the image string in the body, using a json like this:
{
"picture" : "data:image/png;base64,this-is-the-base64-encode-string"
}
In the controller try a lot of differents ways for decode the image and try to pass the validation:
First I tried this:
$data = request->input('picture');
$data = str_replace('data:image/png;base64,', '', $data);
$data = str_replace(' ', '+', $data);
$image = base64_decode($data);
$file = app_path() . uniqid() . '.png';
$success = file_put_contents($file, $image);
Then I tried this:
list($type, $data) = explode(';', $data);
list(, $data) = explode(',', $data);
$data = base64_decode($data);
$typeFile = explode(':', $type);
$extension = explode('/', $typeFile[1]);
$ext = $extension[1];
Storage::put(public_path() . '/prueba.' . $ext, $data);
$contents = Storage::get(base_path() . '/public/prueba.png');
Try to use the intervention image library (http://image.intervention.io/) and don't pass:
$image = Image::make($data);
$image->save(app_path() . 'test2.png');
$image = Image::make(app_path() . 'test1.png');
This is the validation in the controller:
$data = [
'picture' => $image,
'first_name' => $request->input('first_name'),
'last_name' => $request->input('last_name')
];
$validator = Validator::make($data, User::rulesForUpdate());
if ($validator->fails()) {
return $this->respondFailedParametersValidation('Parameters failed validation for a user picture');
}
this is the validation in the User-model:
public static function rulesForUpdate() {
return [
'first_name' => 'max:255',
'last_name' => 'max:255',
'picture' => 'image|max:5000|mimes:jpeg,png'
];
}
Base64 does some padding for you using the = character at the end. If that padding is invalid, it's not a correct base64 encoding, even though it matches your regex. You can demo this by finding a base 64 string with 1 or 2 = at the end, removing them, and trying to decode it.
Images encoded with Base64 can be embedded in HTML by using the <img> tag. This can help to increase the page load time for smaller images by saving the browser from making additional HTTP requests.
'png'; \File::put(storage_path(). '/' . $imageName, base64_decode($image)); This the Code for covert any Base64 String to Image and store theme in a local path with file name.
If you are using Intervention anyways, then you can leverage it for a custom validation rule. I have one called "imageable". It basically makes sure that the input given will be able to be converted to an Intervention image. Base64 data image strings will pass. A string of "foo" will not.
Validator::extend('imageable', function ($attribute, $value, $params, $validator) {
try {
ImageManagerStatic::make($value);
return true;
} catch (\Exception $e) {
return false;
}
});
This obviously just checks that the input is able to be converted to an image. However, it should show you as a use-case how you can leverage Intervention and any of it's methods to create a custom rule.
You can extend the Validator class of Laravel.
Laravel Doc
But anyway try this
Validator::extend('is_png',function($attribute, $value, $params, $validator) {
$image = base64_decode($value);
$f = finfo_open();
$result = finfo_buffer($f, $image, FILEINFO_MIME_TYPE);
return $result == 'image/png';
});
Don't forget the rules:
$rules = array(
'image' => 'is_png'
);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With