I'm using intervention image on my Lumen project and everything works until I come across on making the encoded image as a downloadable response which upon form submit that contains the image file that will be formatted unto specific format e.g. webp, jpg, png will be sent back as a downloadable file to the user, below is my attempt.
public function image_format(Request $request){
$this->validate($request, [
'image' => 'required|file',
]);
$raw_img = $request->file('image');
$q = (int)$request->input('quality',100);
$f = $request->input('format','jpg');
$img = Image::make($raw_img->getRealPath())->encode('webp',$q);
header('Content-Type: image/webp');
echo $img;
}
but unfortunately, its not my expected output, it just did display the image.
from this post, I use the code and attempt to achieve my objective
public function image_format(Request $request){
$this->validate($request, [
'image' => 'required|file',
]);
$raw_img = $request->file('image');
$q = (int)$request->input('quality',100);
$f = $request->input('format','jpg');
$img = Image::make($raw_img->getRealPath())->encode('webp',$q);
$headers = [
'Content-Type' => 'image/webp',
'Content-Disposition' => 'attachment; filename='. $raw_img->getClientOriginalName().'.webp',
];
$response = new BinaryFileResponse($img, 200 , $headers);
return $response;
}
but its not working, instead it showed me this error
any help, ideas please?
In Laravel you could use the response()->stream(), however, as mentioned in the comments, Lumen doesn't have a stream method on the response. That being said the stream() method is pretty much just a wrapper to return a new instance of StreamedResponse (which should already be included in your dependencies).
Therefore, something like the following should work for you:
$raw_img = $request->file('image');
$q = (int)$request->input('quality', 100);
$f = $request->input('format', 'jpg');
$img = Image::make($raw_img->getRealPath())->encode($f, $q);
return new \Symfony\Component\HttpFoundation\StreamedResponse(function () use ($img) {
echo $img;
}, 200, [
'Content-Type' => 'image/jpeg',
'Content-Disposition' => 'attachment; filename=' . 'image.' . $f,
]);
Related
I have searched a lot but did not find a working solution.
I have been trying to convert a QRcode SVG file to PNG format.
The following does return an empty black image but with no content. I would like to convert from the SVG format to PNG format with all the contents:
$file = SVG::fromFile(storage_path('app/public/qr_background.svg'));
$background = $file->getDocument();
$qrString = QrCode::size('2500')
->style('round')
->backgroundColor(0,0,0,1)
->generate(
env('FARMCODE_BASE_URL')
? env('FARMCODE_BASE_URL') . $product->id
: route('product-landingpage', ['product' => $product])
);
$qr = SVG::fromString($qrString)->getDocument();
$qr->getChild(1)->setAttribute('transform', "translate(450,450) scale(44)");
$background->addChild($qr);
$name = 'abc.png';
// Make image with Laravel Invervention package
$image = Image::make($file->toRasterImage(2000,2000))->encode('png');
$headers = [
'Content-Type' => 'image/png',
'Content-Disposition' => 'attachment; filename='. $name,
];
return response()->stream(function() use ($image) {
echo $image;
}, 200, $headers);
I am using meyfa/php-svg simplesoftwareio/simple-qrcode and intervention/image
I am uploading an image on my form then resizing it using a library. I can upload the pic with no problem here is my code:
public function store()
{
$this->validate(request(),[
'title'=>'required',
'body'=>'required|min:5 ',
'photo' => 'required|image|mimes:jpeg,png,jpg,gif,svg|max:2048'
]);
$image = request()->file('photo');
$fileName = $image->getClientOriginalName();
$publicPath = 'images/';
$image_resize = Image::make($image->getRealPath());
$image_resize->resize(1200, 800);
$image_resize->save($publicPath.$fileName);
auth()->user()->addPost(new Posts( [
'title'=>request('title'),
'body'=>request('body'),
'photo'=> $fileName
]));
return redirect('/');
}
my issue is that the image doesn't show up on my front view. I have tried to remove the resizing its still the same
Well the issue here is that when u are saving the post on database photo option u are saving only the filename, you should concatinate your public path with the image path like so: 'photo'=> $publicPath.$fileName
$image = request()->file('photo');
$fileName = $image->getClientOriginalName();
$publicPath = 'images/';
$image_resize = Image::make($image->getRealPath());
$image_resize->resize(1200, 800);
$image_resize->save($publicPath.$fileName);
auth()->user()->addPost(new Posts( [
'title'=>request('title'),
'body'=>request('body'),
'photo'=> $publicPath.$fileName
]));
So try now it should work.
I have the following route that will load a file from the given URL, I need this to actually download the file (mp4, jpg, pdf) rather than open in the browsers in built viewer.
// Download from CDN Route
Route::get('cdn/{url}', function($url)
{
return Redirect::away($url);
})->where('url', '(.*)');
All files are stored externally so apparently Resource::download() wouldn't actually work.
All I have available to me is the Amazon URL: https://mybucket.s3.amazonaws.com/folder/filename.pdf
Any suggestions on how to force the browser to download the file from S3?
In my case simple anchor link is downloading the file ...
file name
Try this code.
Update composer with flysystem
$path = 'https://mybucket.s3.amazonaws.com/folder/filename.pdf';
if(Storage::disk('s3')->has($path)){
$data = Storage::disk('s3')->get($path);
$getMimeType = Storage::disk('s3')->getMimetype($path);
$newFileName = 'filename.pdf';
$headers = [
'Content-type' => $getMimeType,
'Content-Disposition'=>sprintf('attachment; filename="%s"', $newFileName)
];
return Response::make($data, 200, $headers);
}
pari answer download empty file.
$s3Client = AWS::createClient('s3');
$stream = $s3Client->getObject(
[
'Bucket' => 'bucket name',
'Key' => 'filename',
'SaveAs' => '/tmp'.filename
]);
return response($stream['Body'], 200)->withHeaders([
'Content-Type' => $stream['ContentType'],
'Content-Length' => $stream['ContentLength'],
'Content-Disposition' => 'attachment; filename="' .{filename with extention} . '"'
]);
How can we download a video with an external link from another server. It's not s3. It's a normal server, files are there, but it doesn't work. I have written this code
$filename = $video->video_id;
$tempFile = tempnam(sys_get_temp_dir(), $filename);
// dd($tempFile);
copy($video->path, $tempFile);
header("Content-Disposition: attachment; filename = ".$filename);
header("X-Accel-Redirect: ".$filename);
return response()->download($tempFile, $filename);
I am using Laravel's Storage facade and I am able to upload the pdf to S3 and I am also able to get() its contents but I cannot display or download it to the end user as an actual pdf file. It just looks like raw data. Here is the code:
$file = Storage::disk($storageLocation)->get($urlToPDF);
header("Content-type: application/pdf");
header("Content-Disposition: attachment; filename='file.pdf'");
echo $file;
How can this be done? I have checked several articles (and SO) and none of them have worked for me.
I think something like this will do the job in L5.2:
public function download($path)
{
$fs = Storage::getDriver();
$stream = $fs->readStream($path);
return \Response::stream(function() use($stream) {
fpassthru($stream);
}, 200, [
"Content-Type" => $fs->getMimetype($path),
"Content-Length" => $fs->getSize($path),
"Content-disposition" => "attachment; filename=\"" .basename($path) . "\"",
]);
}
you can create a download url, using the getObjectUrl method
somthing like this:
$downloadUrl = $s3->getObjectUrl($bucketname, $file, '+5 minutes', array(
'ResponseContentDisposition' => 'attachment; filename=$file,'Content-Type' => 'application/octet-stream',
));
and pass that url to the user. that will direct the user to an amzon page which will start the file download (the link will be valid for 5 minutes - but you can change that)
another option, is first saving that file to your server, and then let the user download the file from your server
You can do with this code (replace with your directory and your file name) ....
Storage::disk('s3')->download('bucket-directory/filename');
If your bucket is private, this is the way to obtain a url to download the file.
$disk = \Storage::disk('s3');
if ($disk->exists($file)) {
$command = $disk->getDriver()->getAdapter()->getClient()->getCommand('GetObject', [
'Bucket' => \Config::get('filesystems.disks.s3.bucket'),
'Key' => $file,
'ResponseContentDisposition' => 'attachment;'
]);
$request = $disk->getDriver()->getAdapter()->getClient()->createPresignedRequest($command, '+5 minutes');
$url = (string)$request->getUri();
return response()->json([
'status' => 'success',
'url' => $url
]);
}
In Laravel 5.7 it can be done with streamDownload:
return response()->streamDownload(function() use ($attachment) {
echo Storage::get($attachment->path);
}, $attachment->name);
$filename = 'test.pdf';
$filePath = storage_path($filename);
$header = [
'Content-Type' => 'application/pdf',
'Content-Disposition' => 'inline; filename="'.$filename.'"'
];
return Response::make(file_get_contents($filePath), 200, $header);
$d = file_full_path_here...
$d = str_replace(' ', '%20', $d); //remove the white space in url
ob_end_clean();
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-Disposition: attachment; filename=" . $d);
header("Content-Type: application/pdf");
return readfile($d);
I figured it out. Silly mistake. I had to remove the single quotes from filename.
Fix:
$file = Storage::disk($storageLocation)->get($urlToPDF);
header("Content-type: application/pdf");
header("Content-Disposition: attachment; filename=file.pdf");
echo $file;
This is the line of code which is giving me sick.
return Response::download(storage_path().'/file/' . $file->id . "." . $file->file->extension);
The files are uploaded and given an id which they are saved under e.g. 25.pdf this works fine if the file is a PDF but doesn't for anything else e.g. PNG. we upgraded from Laravel 3 to 4 to try to overcome this problem.
Any ideas?
EDIT:
I just uploaded a test text file with the word test in it once I uploaded it and then downloaded it I opened it, there were 3 blank lines and the letters te!!!!!I downloaded it through sftp and the file is correctly stored on the server so it is defiantly the download procedure!
I used this function instead of any of the Laravel stuff. :/
(Stolen from other places around the web)
public static function big_download($path, $name = null, array $headers = array()) {
if (is_null($name))
$name = basename($path);
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$pathParts = pathinfo($path);
// Prepare the headers
$headers = array_merge(array(
'Content-Description' => 'File Transfer',
'Content-Type' => finfo_file($finfo, $path),
'Content-Transfer-Encoding' => 'binary',
'Expires' => 0,
'Cache-Control' => 'must-revalidate, post-check=0, pre-check=0',
'Pragma' => 'public',
'Content-Length' => File::size($path),
'Content-Disposition' => 'inline; filename="' . $name . '.' . $pathParts['extension'] . '"'
), $headers);
finfo_close($finfo);
$response = new Symfony\Component\HttpFoundation\Response('', 200, $headers);
// If there's a session we should save it now
if (Config::get('session.driver') !== '') {
Session::save();
}
// Below is from http://uk1.php.net/manual/en/function.fpassthru.php comments
session_write_close();
ob_end_clean();
$response->sendHeaders();
if ($file = fopen($path, 'rb')) {
while (!feof($file) and (connection_status() == 0)) {
print(fread($file, 1024 * 8));
flush();
}
fclose($file);
}
// Finish off, like Laravel would
Event::fire('laravel.done', array($response));
$response->foundation->finish();
exit;
}
One may ask, How can i get path to file in laravel?
Path to file can be achieved like:
public function getDownload(){
$file = public_path()."/downloads/info.pdf";
$headers = array('Content-Type: application/pdf',);
return Response::download($file, 'info.pdf',$headers);
}
function will download file from : 'project/public/download' folder.
(don't forget to set-up routes and controller by your self)
Try including the MIME in the return:
$file = storage_path().'/file/' . $file->id . "." . $file->file->extension;
return Response::download($file, 200, array('content-type' => 'image/png'));
If you are using Windows, go to php.ini and then uncomment "extension=php_fileinfo.dll" section and then use this code:
Route::get('file/download', function()
{
$file = public_path(). '\download\myfile.png';
return Response::download($file);
});