Related
I can decode base64 to PNG, but when I try to decode to JPG I got the problem.
Code to decode png
$image = $request['profile_image']; // your base64 encoded
$image = str_replace('data:image/png;base64,', '', $image);
$image = str_replace(' ', '+', $image);
$imageName = 'aaaa'.'.'.'png';
\File::put(public_path() .'/admin_assets/assets/images/users/' . $imageName, base64_decode($image));
Code decode to jpg
$image = $request['profile_image']; // your base64 encoded
$image = str_replace('data:image/jpeg;base64,', '', $image);
$image = str_replace(' ', '+', $image);
$imageName = 'aaaa'.'.'.'jpg';
\File::put(public_path() .'/admin_assets/assets/images/users/' . $imageName, base64_decode($image));
The result from the second code
http://prnt.sc/oysxqn
You can use this function for that base64_decode_image() (It's GitHub link I wrote a function)
Function return array (file and type), but if is image format not allowed it fill return false.
Usage
$AllowedFormats = array('jpg', 'png'); // Here we declare allowed formats
$ProfilImage = $request['profile_image'];
$Image = base64_decode_image($ProfilImage, $AllowedFormats);
// Here we checking if is returned array or not
if(!is_array($Image )){
echo 'Wrong image format';
die(); // if is image format not allowed it will stop scrip and throw an error
}
$type = $Image['type']; // type is file extension as well
$DecodedImage = $Image['file']; // Decoded image file
$ImageName = 'whet-every-you-wanna.'.$type;
// Then you can upload your image
\File::put(public_path() .'/admin_assets/assets/images/users/' . $imageName, $DecodedImage);
Here is how I get my image:
$coverurl = 'https://api.someurl/api/v1/img/' . $somenumber . '/l';
//$iheaders contains: 'Content-type' => 'image/jpeg'
$iresponse = wp_remote_get($coverurl, $iheaders);
$img = $iresponse['body'];
$testimg = base64_encode($img);
When I echo $testimg with an img-tag, everything works fine.
echo '<img class="attachment-shop_single size-shop_single wp-post-image" src="data:image/jpeg;base64,'.$testimg.'" width="274" />';
Since I need to convert the string into a jpg and save it to my uploads folder, I tried to use imagecreatefromstring().
$imgx = imagecreatefromstring($testimg);
if ($imgx !== false) {
header('Content-Type: image/jpeg');
imagejpeg($imgx);
imagedestroy($imgx);
} else {
echo 'An error occurred.';
}
But I never get to the point of saving anything, because of the following warning:
Warning: imagecreatefromstring(): Data is not in a recognized format in /etc.
When I echo $testimg I get:
/9j/4AAQSkZJRgABAQAAAQABAAD ...Many number and characters.. Ggm2JUsEvfqnxAhGFDP/9k=
What must I do to make createimagefromstring work? Do I have to modify the $testimg string? Thanks for your interest.
The method imagecreatefromstring does not take a base_64 encoded string. Try this instead:
$imgx = imagecreatefromstring($img); // Contents of $iresponse['body']
You can see this in the topmost comment in the documentation page (linked above):
<?php
$data = 'iVBORw0KGgoAAAANSUhEUgAAABwAAAASCAMAAAB/2U7WAAAABl'
. 'BMVEUAAAD///+l2Z/dAAAASUlEQVR4XqWQUQoAIAxC2/0vXZDr'
. 'EX4IJTRkb7lobNUStXsB0jIXIAMSsQnWlsV+wULF4Avk9fLq2r'
. '8a5HSE35Q3eO2XP1A1wQkZSgETvDtKdQAAAABJRU5ErkJggg==';
$data = base64_decode($data);
$im = imagecreatefromstring($data);
After looking at the codex https://codex.wordpress.org/Function_Reference/wp_insert_attachment, I found the solution:
//get the image from internet
$coverurl = 'https://api.someurl/api/v1/img/' . $somenumber . '/l';
$iresponse = wp_remote_get($coverurl, $iheaders);
$img = $iresponse['body'];
$directory = "/".date('Y')."/".date('m')."/";
$wp_upload_dir = wp_upload_dir();
//encode $img as with html image tag
$imgdata = base64_encode($img);
$filename = "gtb_". $isbnraw.".jpg";
$fileurl = "../wp-content/uploads".$directory.$filename;
$filetype = wp_check_filetype( basename($fileurl), null);
file_put_contents($fileurl, $img);
$attachment = array(
'guid' => $wp_upload_dir['url'] . '/' . basename( $fileurl ),
'post_mime_type' => $filetype['type'],
'post_title' => preg_replace('/\.[^.]+$/', '', basename($fileurl)),
'post_content' => '',
'post_status' => 'inherit'
);
$attach_id = wp_insert_attachment($attachment, $fileurl, $post_id);
require_once('../wp-admin/includes/image.php');
// Generate the metadata for the attachment, and update the database record.
$attach_data = wp_generate_attachment_metadata($attach_id, $fileurl);
wp_update_attachment_metadata($attach_id, $attach_data);
set_post_thumbnail($post_id, $attach_id);
//add media_category
wp_set_object_terms($attach_id, $mediacat, 'media_category');
This converts a base64 into a jpg and imports it into Wordpress plus attaches it to the post/product. It seems to work well. Thanks for your interest.
This question already has answers here:
How to save a PNG image server-side, from a base64 data URI
(17 answers)
Closed 3 years ago.
I am trying to convert my base64 image string to an image file. This is my Base64 string:
http://pastebin.com/ENkTrGNG
Using following code to convert it into an image file:
function base64_to_jpeg( $base64_string, $output_file ) {
$ifp = fopen( $output_file, "wb" );
fwrite( $ifp, base64_decode( $base64_string) );
fclose( $ifp );
return( $output_file );
}
$image = base64_to_jpeg( $my_base64_string, 'tmp.jpg' );
But I am getting an error of invalid image, whats wrong here?
The problem is that data:image/png;base64, is included in the encoded contents. This will result in invalid image data when the base64 function decodes it. Remove that data in the function before decoding the string, like so.
function base64_to_jpeg($base64_string, $output_file) {
// open the output file for writing
$ifp = fopen( $output_file, 'wb' );
// split the string on commas
// $data[ 0 ] == "data:image/png;base64"
// $data[ 1 ] == <actual base64 string>
$data = explode( ',', $base64_string );
// we could add validation here with ensuring count( $data ) > 1
fwrite( $ifp, base64_decode( $data[ 1 ] ) );
// clean up the file resource
fclose( $ifp );
return $output_file;
}
An easy way I'm using:
file_put_contents($output_file, file_get_contents($base64_string));
This works well because file_get_contents can read data from a URI, including a data:// URI.
You need to remove the part that says data:image/png;base64, at the beginning of the image data. The actual base64 data comes after that.
Just strip everything up to and including base64, (before calling base64_decode() on the data) and you'll be fine.
maybe like this
function save_base64_image($base64_image_string, $output_file_without_extension, $path_with_end_slash="" ) {
//usage: if( substr( $img_src, 0, 5 ) === "data:" ) { $filename=save_base64_image($base64_image_string, $output_file_without_extentnion, getcwd() . "/application/assets/pins/$user_id/"); }
//
//data is like: data:image/png;base64,asdfasdfasdf
$splited = explode(',', substr( $base64_image_string , 5 ) , 2);
$mime=$splited[0];
$data=$splited[1];
$mime_split_without_base64=explode(';', $mime,2);
$mime_split=explode('/', $mime_split_without_base64[0],2);
if(count($mime_split)==2)
{
$extension=$mime_split[1];
if($extension=='jpeg')$extension='jpg';
//if($extension=='javascript')$extension='js';
//if($extension=='text')$extension='txt';
$output_file_with_extension=$output_file_without_extension.'.'.$extension;
}
file_put_contents( $path_with_end_slash . $output_file_with_extension, base64_decode($data) );
return $output_file_with_extension;
}
That's an old thread, but in case you want to upload the image having same extension-
$image = $request->image;
$imageInfo = explode(";base64,", $image);
$imgExt = str_replace('data:image/', '', $imageInfo[0]);
$image = str_replace(' ', '+', $imageInfo[1]);
$imageName = "post-".time().".".$imgExt;
Storage::disk('public_feeds')->put($imageName, base64_decode($image));
You can create 'public_feeds' in laravel's filesystem.php-
'public_feeds' => [
'driver' => 'local',
'root' => public_path() . '/uploads/feeds',
],
if($_SERVER['REQUEST_METHOD']=='POST'){
$image_no="5";//or Anything You Need
$image = $_POST['image'];
$path = "uploads/".$image_no.".png";
$status = file_put_contents($path,base64_decode($image));
if($status){
echo "Successfully Uploaded";
}else{
echo "Upload failed";
}
}
This code worked for me.
<?php
$decoded = base64_decode($base64);
$file = 'invoice.pdf';
file_put_contents($file, $decoded);
if (file_exists($file)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.basename($file).'"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
readfile($file);
exit;
}
?>
$datetime = date("Y-m-d h:i:s");
$timestamp = strtotime($datetime);
$image = $_POST['image'];
$imgdata = base64_decode($image);
$f = finfo_open();
$mime_type = finfo_buffer($f, $imgdata, FILEINFO_MIME_TYPE);
$temp=explode('/',$mime_type);
$path = "uploads/$timestamp.$temp[1]";
file_put_contents($path,base64_decode($image));
echo "Successfully Uploaded->>> $timestamp.$temp[1]";
This will be enough for image processing. Special thanks to Mr. Dev Karan Sharma
I send a png image file to controller in base64 via Ajax. I've already test and sure that controller has received id but still can't save it to public folder.
Here is my controller
public function postTest() {
$data = Input::all();
//get the base-64 from data
$base64_str = substr($data->base64_image, strpos($data->base64_image, ",")+1);
//decode base64 string
$image = base64_decode($base64_str);
$png_url = "product-".time().".png";
$path = public_path('img/designs/' . $png_url);
Image::make($image->getRealPath())->save($path);
// I've tried using
// $result = file_put_contents($path, $image);
// too but still not working
$response = array(
'status' => 'success',
);
return Response::json( $response );
}
Intervention Image gets binary data using file_get_content function:
Reference : Image::make
Your controller should be look like this:
public function postTest() {
$data = Input::all();
$png_url = "product-".time().".png";
$path = public_path().'img/designs/' . $png_url;
Image::make(file_get_contents($data->base64_image))->save($path);
$response = array(
'status' => 'success',
);
return Response::json( $response );
}
$data = Input::all();
$png_url = "perfil-".time().".jpg";
$path = public_path() . "/img/designs/" . $png_url;
$img = $data['fileo'];
$img = substr($img, strpos($img, ",")+1);
$data = base64_decode($img);
$success = file_put_contents($path, $data);
print $success ? $png_url : 'Unable to save the file.';
$file = base64_decode($request['image']);
$safeName = str_random(10).'.'.'png';
$success = file_put_contents(public_path().'/uploads/'.$safeName, $file);
print $success;
This is an easy mistake.
You are using public_path incorrectly. It should be:
$path = public_path() . "/img/designs/" . $png_url;
Also, I would avoid your method of sending the image. Look at a proper upload in a form and use Laravel's Input::file method.
My solution is:
public function postTest() {
$data = Input::all();
//get the base-64 from data
$base64_str = substr($data->base64_image, strpos($data->base64_image, ",")+1);
//decode base64 string
$image = base64_decode($base64_str);
Storage::disk('local')->put('imgage.png', $image);
$storagePath = Storage::disk('local')->getDriver()->getAdapter()->getPathPrefix();
echo $storagePath.'imgage.png';
$response = array(
'status' => 'success',
);
return Response::json( $response );
}
what am i doing is using basic way
$file = base64_decode($request['profile_pic']);
$folderName = '/uploads/users/';
$safeName = str_random(10).'.'.'png';
$destinationPath = public_path() . $folderName;
file_put_contents(public_path().'/uploads/users/'.$safeName, $file);
//save new file path into db
$userObj->profile_pic = $safeName;
}
Store or save base64 images in the public folder image and return file path.
$folderPath = public_path() . '/' . 'images/';
$image_parts = explode(";base64,", $image);
$image_type_aux = explode("image/", $image_parts[0]);
$image_type = $image_type_aux[1];
$image_base64 = base64_decode($image_parts[1]);
$uniqid = uniqid();
$file = $folderPath . $uniqid . '.' . $image_type;
file_put_contents($file, $image_base64);
return $file;
Actually, Input::all() returns an array of inputs so you have following:
$data = Input::all();
Now your $data is an array not an object so you are trying to access the image as an object like:
$data->base64_image
So, it's not working. You should try using:
$image = $data['base64_image'];
Since it's (base64_image) accessible from $_POST then Input::file('base64_image') won't work because Input::file('base64_image') checks the $_FILES array and it's not there in your case.
Here is my solution for the file upload from base_64.
public static function uploadBase64File(Request $request, $requestName = 'imageData', $fileName = null, $uploadPath = 'uploads/images/')
{
try {
$requestFileData = $request->$requestName;
// decode the base64 file
$file = base64_decode(preg_replace(
'#^data:([^;]+);base64,#',
'',
$request->input($requestName)
));
if (in_array($file, ["", null, ' '])) {
return null;
}
//handle base64 encoded images here
if ($fileName == null) {
$fileName = Str::random(10);
}
$extension = '.' . explode('/', explode(':', substr($requestFileData, 0, strpos($requestFileData, ';')))[1])[1];
$filePath = $uploadPath . '' . $fileName . '' . $extension;
// dd($extension);
if (!File::exists(public_path($uploadPath))) {
File::makeDirectory(public_path($uploadPath), 0777, true);
}
// dd($filePath);
$ifImageUploadSuccessful = File::put(public_path($filePath), $file);
if (!$ifImageUploadSuccessful) {
return null;
}
return '/' . $filePath;
// throw new Exception("Unable To upload Image");
} catch (Exception $e) {
// dd($e);
throw new Exception($e->getMessage());
}
}
I'v done it!!
I replaced
$data->base64_image to $_POST['base64_image'] and then use
$result = file_put_contents($path, $image);
instead of Image::make($image->getRealPath())->save($path);
But this doesn't look like a laravel ways. I you have another way that look more elegant please tell me!
I'm letting my users crop & upload their image with jQuery FileAPI. I'm calling this PHP file with jQuery from another page.
Everything works good on my local server, but when uploading it to my production (shared - cPanel) server, it does not create the file.
Do you know if there is something that I need to change on my cPanel or call my hosting company for?
I tried tweeking with header access but nothing works.
Here is the PHP file:
<?php include 'init.php'; ?>
<?php
if(logged_in() === false) {
header('Location: login.php');
exit();
} ?>
<?php
/**
* FileAPI upload controller (example)
*/
include 'FileAPI.class.php';
if( $_SERVER['REQUEST_METHOD'] == 'OPTIONS' ){
exit;
}
if( strtoupper($_SERVER['REQUEST_METHOD']) == 'POST' ){
$files = FileAPI::getFiles(); // Retrieve File List
$images = array();
// Fetch all image-info from files list
fetchImages($files, $images);
// JSONP callback name
$jsonp = isset($_REQUEST['callback']) ? trim($_REQUEST['callback']) : null;
// JSON-data for server response
$json = array(
'images' => $images
, 'data' => array('_REQUEST' => $_REQUEST, '_FILES' => $files)
);
// Server response: "HTTP/1.1 200 OK"
FileAPI::makeResponse(array(
'status' => FileAPI::OK
, 'statusText' => 'OK'
, 'body' => $json
), $jsonp);
exit;
}
function fetchImages($files, &$images, $name = 'file'){
if( isset($files['tmp_name']) ){
$filename = $files['tmp_name'];
list($mime) = explode(';', #mime_content_type($filename));
if( strpos($mime, 'image') !== false ){
$size = getimagesize($filename);
$base64 = base64_encode(file_get_contents($filename));
$images[$name] = array(
'width' => $size[0]
, 'height' => $size[1]
, 'mime' => $mime
, 'size' => filesize($filename)
, 'dataURL' => 'data:'. $mime .';base64,'. $base64
);
$iWidth = $iHeight = 330; // desired image result dimensions
$iJpgQuality = 100;
// new unique filename
$sTempFileName = 'userpics/' . md5(time().rand());
// move uploaded file into cache folder
move_uploaded_file($filename, $sTempFileName);
// change file permission to 644
#chmod($sTempFileName, 0644);
if (file_exists($sTempFileName) && filesize($sTempFileName) > 0) {
$aSize = getimagesize($sTempFileName); // try to obtain image info
if (!$aSize) {
#unlink($sTempFileName);
return;
}
// check for image type
switch($aSize[2]) {
case IMAGETYPE_JPEG:
$sExt = '.jpg';
// create a new image from file
$vImg = #imagecreatefromjpeg($sTempFileName);
break;
case IMAGETYPE_GIF:
$sExt = '.gif';
// create a new image from file
$vImg = #imagecreatefromgif($sTempFileName);
break;
case IMAGETYPE_PNG:
$sExt = '.png';
// create a new image from file
$vImg = #imagecreatefrompng($sTempFileName);
break;
default:
#unlink($sTempFileName);
return;
}
$data = getimagesize($sTempFileName);
$width = $data[0];
$height = $data[1];
// create a new true color image
$vDstImg = #imagecreatetruecolor( $iWidth, $iHeight );
// copy and resize part of an image with resampling
imagecopyresampled($vDstImg, $vImg, 0, 0, 0, 0, $iWidth, $iHeight, $width, $height);
// define a result image filename
$sResultFileName = $sTempFileName . $sExt;
// output image to file
imagejpeg($vDstImg, $sResultFileName, $iJpgQuality);
#unlink($sTempFileName);
$user_id = $_SESSION['user_id'];
add_guest_picture($user_id, $sResultFileName);
// return $sResultFileName;
}
}
}
else {
foreach( $files as $name => $file ){
fetchImages($file, $images, $name);
}
}
}
?>
Ok issue resolved!
Apparently mime_content_type was not support by my host. after removing error suppression recommended by Musa I could catch the error.
I asked for my host to enable my mime php handling and now everything works.
Cheers.