spatie medialibrary defining fallback image for each convertion - php

with spatie/medialibrary package i have 3 conversions in registerMediaConversions method like this
public function registerMediaConversions(Media $media = null): void
{
$this->addMediaConversion('thumb')
->fit(MANIPULATIONS::FIT_STRETCH, 140, 260);
$this->addMediaConversion('slider')
->fit(MANIPULATIONS::FIT_STRETCH, 275, 720);
$this->addMediaConversion('mini')
->fit(MANIPULATIONS::FIT_STRETCH, 55, 85);
}
the thing i want is that i can define a useFallbackUrl image for each of these conversions. i know i can define fallback image on registerMediaCollections method, but this will apply on every conversion, instead i want to define a different fallback image for each one of them.
how can i do that?

Related

How to set custom page size in fpdf php library?

I need some help with fPDF. I want to set up my custom page size (exactly: width 3 inch, and height 5 or 6 inch).
it will create number of pages again height parameter .
i set the size array(3,5). it will create 5 page. I
found fPDF() manual (http://www.fpdf.org/) but there are only ready formats like A4, B5 etc. I have to set up my own page format.
<?php
require_once('fpdf/fpdf.php');
//$fromat = array(3,5);
$pdf = new FPDF('p','in', [4.1,2.9]);
$pdf->SetTopMargin(50);
$pdf->Addpage();
$pdf->SetTitle("invoice");
$pdf->SetCreator("maqbool solutons");
$pdf->SetAuthor("my name");
$pdf->SetSubject("report");
$pdf->SetFont('Arial', 'B', '16');
$pdf->SetTextColor(155,14,9);// rgb
$pdf->SetDrawColor(155,14,9);
$pdf->SetfillColor(15,140,95);
$pdf->Cell(60,10, 'hello word');
$pdf->Cell(60,10,'powered by fpdf', 1, 0,'c',true);
$pdf->Cell(60,10,'powered by fpdf', 1, 2,'c');
$pdf->Cell(60,10,'powered by fpdf', 1, 1,'c');
$pdf->Image("images/coat.jpg", 10,20,10,35);
$pdf->MultiCell(94,10,"skldjfsldfsfjsdkfsjdlfjsdflkjsdflksjflksjdflskjfslkjfdslkfdjslkfdjslkfjslkfjslkfjsflkjsflkjsflksjflksjfslkjfslkjslkf",1,"L",false);
$pdf->Output("I", "invice.pdf");
?>[that is my file size][1]
when i add array of size
You should should define it in your constructor like so:
$pdf = new FPDF('P','in',[3,6]);
You can find more info in tutorial #1 and in the manual > AddPage
As said in the documentation, when you call the constructor or AddPage, you can either give a String or an Array containing the width and height:
// AddPage([string orientation [, mixed size [, int rotation]]])
$pdf->AddPage("P", [3, 5]); // assuming you are using 'in' as unit
Or directly using the constructor:
// __construct([string orientation [, string unit [, mixed size]]])
$pdf = new FPDF('P','in',[3, 5]);
I think you can set the page size with the constructor.
I have not tested it but this should show you the way:
$format=array(3,5);
$pdf=new FPDF('P','in',$format);
$pdf->Open();
....

How can reduce height and download pdf using FPDF?

I have a function to generate pdf using Fpdf in laravel.
My problems are:
After all Cell I have some extra space. I need to remove that. Please find the image given below.
How can I download this pdf file in to my system. Currently it's just showing in to browser. Code samples are given below.
Code
Controller: Controller.php
public function index()
{
$orders = Order::select('firstname', 'lastname', 'street', 'postal', 'country')->get();
foreach ($orders as $order){
Fpdf::SetMargins(5, 5, 5);
Fpdf::AddPage('L', array(60,90), 'A4');
Fpdf::SetAutoPageBreak(TRUE, 0);
Fpdf::SetFont('helvetica', '', 7); //IF bold letter SetFont('Arial','B',14)
Fpdf::SetTextColor(0, 0, 0);
Fpdf::Cell(10,5,iconv('UTF-8', 'windows-1252', 'Falls unzustellbar, zurück an Absender'),0,"1","L");
Fpdf::SetFont('','U');
Fpdf::Cell(10,5,iconv('UTF-8', 'windows-1252', 'schrillALARM.jetzt c/o 365group • Grasgasse 2 • 93047 Regensburg'),0,"1","L");
Fpdf::SetFont('helvetica', '', 11);
Fpdf::Cell(10,5,$order->firstname,0,1,"L");
Fpdf::Cell(10,5,$order->lastname,0,1,"L");
Fpdf::Cell(10,5,$order->street,0,1,"L");
Fpdf::Cell(10,5,$order->postal,0,1,"L");
Fpdf::Cell(10,5,$order->country,0,1,"L");
}
Fpdf::Output();
exit;
}
Route: Route::get('/test', 'Controller#index');
No experience with FDPF, but you can download this way:
Route::get(
'download/pdf/{pdf}',
function ($pdf) {
$file = // Get file
return response()->download($file);
}
);
Or just from your controller with
return response()->download($pdf);
for saving, just specify output path and filename in your output call string
Fpdf::Output([string dest [, string name [, boolean isUTF8]]])
For your white space though, when you're constructing your PDF document, you can use a default size of one of the following: A3, A4, A5, Letter, Legal with A4 being default. However, you can also declare custom sizes. This is more than likely what you're looking for, as you'll want to play with the sizes to get it with the amount of white space you're looking for. FPDF puts out the canvas first then fills it, so you're white space is coming from a canvas that is too big. This can be done in the constructor, or AddPage as you have done.
VIA Constructor:
//(L)andscape or (P)ortrait, unit type (mm millimeters), array size in mm
$pdf = new FPDF('L','mm',array(100,150));
VIA AddPage (must likely what you're looking for):
currently you have:
Fpdf::AddPage('L', array(60,90), 'A4');
however, params are supposed to be landscape/portrait, Predefined or custom size array, then rotation. So try this:
Fpdf::AddPage('L', array(60,90));
Now you'll need to play with those numbers, more than likely the 90, and shorten that up to rid yourself of the white space.

PHPExcel: print page margins and print auto fit seems not working

I'm calling these 3 functions one after other in this exact order
public function setPrintFitToWidth()
{
$this->sheet->getPageSetup()->setFitToWidth(1);
}
public function setPrintArea($cell_area)
{
$this->sheet->getPageSetup()->setPrintArea($cell_area);
}
public function setPrintMargins($top, $right, $bottom, $left)
{
$this->sheet->getPageMargins()->setTop($top);
$this->sheet->getPageMargins()->setRight($right);
$this->sheet->getPageMargins()->setLeft($left);
$this->sheet->getPageMargins()->setBottom($bottom);
}
The problem is that, opening resulting Excel file, I've page margin set to 'custom' but, in fact, set to different values instead of margin I passed to my function. In fact I called with argument (1,0.5,0.5,1) but I got, in the same orders, 2, 0.8, 0.8, 2. It's really strange ...
Also: I cannot get working setFittoWidth(1); I expect to see adapted for all column in one page, but Excel tell me It's setup on adapt sheet on a page.
What am I doing wrong?
Resolved:
changed
public function setPrintFitToWidth()
{
$this->sheet->getPageSetup()->setFitToWidth(1);
}
to
public function setPrintFitToWidth()
{
$this->sheet->getPageSetup()->setFitToWidth(1);
$this->sheet->getPageSetup()->setFitToHeight(0);
}
About the margins: I tried with zero and margin are respected, so I concluded than PHPExcel unit are in someway 'scaled down'... So, after some 'try' and 'redo', I found the values that generate the correct magins

phpImageWorkshop: Removing a layer after saving

In the phpImageWorkshop documentation (http://phpimageworkshop.com/doc/13/saving.html) it says:
...after saving, you'll be able to continue to use your document and
to perform some actions on its sublayers, really convenient !
However, after calling save() I'm unable to remove the watermark layer.
I start by loading the photo and watermark and resize the photo:
$photo = PHPImageWorkshop\ImageWorkshop::initFromPath($tmp_name);
$mark = PHPImageWorkshop\ImageWorkshop::initFromPath($watermark);
$photo->resizeInPixel(960, null, true);
And then I add the watermark, save the photo, then remove the watermark (so I can make other sizes without a watermark without creating a new object):
$photo->addLayer(1, $mark, 0, 0, 'LB');
$photo->save($path, $filename, false, null, 80); // file correctly has watermark
$photo->remove(1);
$photo->resizeInPixel(550, null, true);
$photo->save($path, $filename, false, null, 80); // file has watermark, not correct
This does not delete the watermark layer. However, if I call remove() before save() it will remove the watermark:
$photo->addLayer(1, $mark, 0, 0, 'LB');
$photo->remove(1); // calling remove() before save removes watermark
$photo->save($path, $filename, false, null, 80); // file does not have watermark
I cannot understand why this is happening, since the documentation clearly says calling save() does not change the layers.
I've confirmed that the watermark layer is being put on layer level 1, and it works OK if I do not call save().
Despite the documentation saying you'll be able to continue to use your document, the fact is that the save() function calls getResult() which returns a merged resource image (this is in ImageWorkshopLayer.php)
However, if you create a 'base layer' and add the photo and watermark on top of it, the save() function appears to merge to the base layer - leaving the photo and mark untouched, so you can remove the mark and re-save (which causes the photo to be re-merged onto the base layer) i.e.
$baseimg = PHPImageWorkshop\ImageWorkshop::initVirginLayer(1024,800);
$photo = PHPImageWorkshop\ImageWorkshop::initFromPath("test.png");
$mark = PHPImageWorkshop\ImageWorkshop::initFromPath("test2.png");
$iphoto= $baseimg->addLayerOnTop($photo, 0, 0, 'LB');
$imark= $baseimg->addLayerOnTop($mark, 0, 0, 'LB');
$baseimg->resizeInPixel(960, null, true);
// file correctly has watermark
$baseimg->save(__DIR__, "test_out.png", false, null, 80);
$baseimg->remove($imark['id']);
// file correctly has no watermark
$baseimg->save(__DIR__, "test_out2.png", false, null, 80);
Note that I use the return value from addLayerOnTop() to determine the 'id' pf the layer to remove.
EDIT: although the above works, it is not ideal because you really need the resulting image to be the size of the re-sized photo. Also I found that once the photo is made a layer, you have to resize that layer (not the original photo) so...
// load photo and mark
$photo = PHPImageWorkshop\ImageWorkshop::initFromPath("test.png");
$mark = PHPImageWorkshop\ImageWorkshop::initFromPath("test2.png");
// resize the photo 1st time
$photo->resizeInPixel(960,null, true);
$width= $photo->getWidth();
$height= $photo->getHeight();
// make empty base image same size as photo
$baseimg = PHPImageWorkshop\ImageWorkshop::initVirginLayer($width,$height);
// add photo and mark onto base image
$iphoto= $baseimg->addLayerOnTop($photo, 0, 0, 'LT');
$imark= $baseimg->addLayerOnTop($mark, 0, 0, 'LT');
$photoid= $iphoto['id']; // get layer id's
$markid= $imark['id'];
// file correctly has watermark
$baseimg->save(__DIR__, "test_out.png", false, null, 80);
// remove mark layer
$baseimg->remove($imark['id']);
// resize photo again
// - photo is now a layer in baseimg
$baseimg->layers[$photoid]->resizeInPixel(550,null, true);
$width= $baseimg->layers[$photoid]->getWidth();
$height= $baseimg->layers[$photoid]->getHeight();
// crop baseimg to match photo size
$baseimg->cropInPixel($width,$height);
// file correctly has no watermark
$baseimg->save(__DIR__, "test_out2.png", false, null, 80);
That seems to work fine now.

Making Greyscale image in Silverstripe

I'd like to be able to return an image in Black&white in a controller, so I can use it in a template. On this page I found that the GD class has a greyscale method. Unfortunately I don't understand the GD class and how I can use it. I tried doing
$final = $image->getFormattedImage('greyscale',36,36,36);
But that didn't work. It does return an image object with a new URL but the image does not exist.
Can anyone explain to me how to make an imageobject into a greyscale image in a Silverstripe page Controller?
Well I had a go myself and this is what I came up with:
_config.php
Object::add_extension('Image', 'Greyscaled');
UPDATE: as of SilverStripe 3.1, you should use the config system instead of _config.php. Put the following in your mysite/_config/config.yml (Don't forget to ?flush=1 to reload the config cache after adding it):
Image:
extensions:
- 'Greyscaled'
Greyscaled.php
<?php
class Greyscaled extends DataExtension {
//This allows the template to pick up "GreyscaleImage" property, it requests a copy of the image from the cache or if it doesn't exist, generates a new one
public function GreyscaleImage($RGB = '76 147 29') {
return $this->owner->getFormattedImage('GreyscaleImage', $RGB);
}
//This is called internally by "generateFormattedImage" when the item is not already cached
public function generateGreyscaleImage(GD $gd, $RGB) {
$Vars = explode(' ', $RGB);
return $gd->greyscale($Vars[0], $Vars[1], $Vars[2]);
}
}
UPDATE2: With newer Versions of 3.1 ?? you can pass in more than 2 parameters and GD has been renamed to Image_Backend. This way you do not have spaces between the RGB-values in the image-name. Be aware $gd->greyscale needs a lot of juice - so you probable better downsize first and GreyscaleImage afterwards.
UPDATE3: Since this answer got some votes recently I assume people still using it, but I think in 2017 CSS filters are in many cases a better choice. Prefixed you'll have close to 90% coverage.
css-filters on caniuse.com
<?php
class Greyscaled extends DataExtension {
public function GreyscaleImage($R = '76', $G = '147', $B = '29') {
return $this->owner->getFormattedImage('GreyscaleImage', $R, $G, $B);
}
public function generateGreyscaleImage(Image_Backend $gd, $R, $G, $B) {
return $gd->greyscale($R, $G, $B);
}
}
and in the template:
<img src="$Images.GreyscaleImage.CroppedImage(1000,400).URL" alt="$Images.Title" />
Silverstripe 3.1 Image API
There is a module for this. Sorry but it's not on packagist just yet.
https://github.com/NightJar/ssrigging-greyscaleimages

Categories