I'm using JpGraph to graph some data. When I use the SetScale function to force a y-axis range the output visually overflows the graph area. I would like to have the output cropped to the graph area.
<?php
require_once ('include/jpgraph/jpgraph.php');
require_once ('include/jpgraph/jpgraph_line.php');
$datay1 = array(20,7,16,46,90,5,0,5,95);
// Setup the graph
$graph = new Graph(400,300);
$graph->title->Set('Graph Title');
$graph->title->font_size = 20;
$graph->SetScale("textlin",20,50);
//this version works but does not set the y-axis scale
//$graph->SetScale("textlin");
$p1 = new LinePlot($datay1);
$graph->Add($p1);
// Output line
$graph->Stroke();
?>
This is the current output:
This is the desired output (rendered by Excel):
I got in touch with the company behind JpGraph and they were able to help. The missing option is:
$graph->setClipping(true);
I hope this helps anyone else who may have a similar issue.
$myMaxY = 50; //You need to set Y Max as you want
$length = count($datay1);
for($i = 0; $i < $lenght; $i++)
{
if($datay1[$i] > $myMaxY)
$datay1[$i] = $myMaxY;
}
$graph->SetScale("textlin",20,$myMaxY); //Dont forget to change this
Related
I want to split slides of one pptx file into seperated pptx files, containing one slide each. The content/text is copied but the layout & styling is not copied. Here is the code.
Can anyone please help ?
<?php
use PhpOffice\PhpPresentation\PhpPresentation;
use PhpOffice\PhpPresentation\IOFactory;
use PhpOffice\PhpPresentation\Style\Color;
use PhpOffice\PhpPresentation\Style\Alignment;
use PhpOffice\PhpPresentation\Slide\SlideLayout;
$objReader = \PhpOffice\PhpPresentation\IOFactory::createReader('PowerPoint2007');
$objPHPPowerPoint = $objReader->load('a.pptx');
$totalSlides = $objPHPPowerPoint->getSlideCount();
$oMasterSlide = $objPHPPowerPoint->getAllMasterSlides()[0];
$documentProperties = $objPHPPowerPoint->getDocumentProperties();
for ( $count = 0; $count < $totalSlides; $count++ ) {
$objPHPPresentation = new PhpPresentation();
$slide = $objPHPPowerPoint->getSlide( $count );
$background = $slide->getBackground();
$newSlide = $objPHPPresentation->addSlide( $slide );
$newSlide->setBackground ( $background );
$objPHPPresentation->setAllMasterSlides( $oMasterSlide );
$objPHPPresentation->removeSlideByIndex(0);
$oWriterPPTX = \PhpOffice\PhpPresentation\IOFactory::createWriter($objPHPPresentation, 'PowerPoint2007');
$oWriterPPTX->save($count.'.pptx');
}
I don't think it's an issue with your code - more an issue with the underlying libraries - as mentioned here: PhpPresentation imagecreatefromstring(): Data is not in a recognized format - PHP7.2
It ran a test to see if it was something I could replicate - and I was able to. The key difference in my test was in one presentation I had a simple background, and in the other it was a gradient.
This slide caused problems:
But this one was copied over fine:
With the more complex background I got errors like:
PHP Warning: imagecreatefromstring(): Data is not in a recognized format
My code is even less complicated than yours, I just clone the original slideshow and remove all except a single slide before saving it:
for ( $count = 0; $count < $totalSlides; $count++ ) {
$copyVersion = clone $objPHPPowerPoint;
foreach ($copyVersion->getAllSlides() as $index => $slide) {
if ($index !== $count) {
$copyVersion->removeSlideByIndex($index);
}
}
$oWriterPPTX = \PhpOffice\PhpPresentation\IOFactory::createWriter($copyVersion, 'PowerPoint2007');
$oWriterPPTX->save($count.'.pptx');
}
Sorry if this doesn't exactly solve your problem, but hopefully it can help identify why it's happening. The other answer I linked to has more information about finding unsupported images types in your slides.
You can try using Aspose.Slides Cloud SDK for PHP to split a presentation into separate slides and save them to many formats. You can evaluate this REST-based API making 150 free API calls per month for API learning and presentation processing. The following code example shows you how to split a presentation and save slides to PPTX format using Aspose.Slides Cloud:
use Aspose\Slides\Cloud\Sdk\Api\Configuration;
use Aspose\Slides\Cloud\Sdk\Api\SlidesApi;
use Aspose\Slides\Cloud\Sdk\Model;
$configuration = new Configuration();
$configuration->setAppSid("my_client_id");
$configuration->setAppKey("my_client_key");
$slidesApi = new SlidesApi(null, $configuration);
$filePath = "example.pptx";
// Upload the file to the default storage.
$fileStream = fopen($filePath, 'r');
$slidesApi->uploadFile($filePath, $fileStream);
// Split the file and save the slides in PPTX format in the same folder.
$response = $slidesApi->split($filePath, null, Model\SlideExportFormat::PPTX);
// Download files of the slides.
foreach($response->getSlides() as $slide) {
$slideFilePath = pathinfo($slide->getHref())["basename"];
$slideFile = $slidesApi->downloadFile($slideFilePath);
echo $slideFile->getRealPath(), "\r\n";
}
Sometimes it is necessary to split a presentation without using any code. In this case, you can use Online PowerPoint Splitter.
I work as a Support Developer at Aspose.
I'm trying to generate a labels for the members. It comes with two things Address and Name. I'm using mpdf to generate pdf. I don't know why mpdf is not generating pdf for twenty second data on-wards.
So, i tried to check it by replacing same data on 21st data on-wards. and again the result is same. I tried like below to create the problem I'm facing.
change for loop increment number from 21 to 22 and that's all...! Mpdf stops working. why only for 21st data it will generate pdf ? I Don't know.
require_once __DIR__ . '/vendor/autoload.php';
$style= "<style>html,body{height:297mm;width:210mm;padding: 8mm 4mm 8mm 4mm} p{font-size:14px;} div{overflow:hidden;width:65mm;height:38mm; float:left;border:1px solid;margin:0;padding:-2 0 -2 5px;} </style>";
for ($x = 0; $x < 21; $x++) {
$data .= "<div style='page-break-inside:avoid;padding:5px;'><p>ANAND S.N.</p><P> #54, M/S, RAJATHA ENTREPRISE V.T.STREET, SARJAPURA POST
BENGALURU RURAL, ANEKAL, 562125</P></div>";
}
$data_print = $style.'<p>'.$data.'</p>';
echo $data_print;
$mpdf = new mPDF();
// $mpdf = new \Mpdf\Mpdf();
$mpdf->WriteHTML($data_print);
$mpdf->Output('mpdf.pdf','D');
I have more then twenty thousand records list and I need to take print on this format. So, will mpdf work or Do i need to go for any other alternatives.
For others who are getting same problem. once check if you gave
ob_start();
after
include('vendor_pdf/vendor/autoload.php');
followed by your php code
and then
$content = ob_get_clean(); // get content of the buffer and clean the buffer
$mpdf = new \Mpdf\Mpdf();
$mpdf->SetDisplayMode('fullpage');
$mpdf->WriteHTML($content);
$mpdf->Output();
I have created an FPDF PDF document that puts an image on label paper which has 9 rows of labels (PHP code below)
There is no space/gap between each row of labels, and the next row of labels start immediately after the previous row.
### THE ISSUE: ###
When the labels are printed, the image displayed on each label moves down slightly from the top of each label, causing the bottom row of labels (9th row) to be significantly different to the 1st couple of rows.
I need to add additional content to each label, and if this issue continues, some of this content is going to get cut off.
I don't understand why this is happening, and can't see anything obvious in the code. Can anyone here spot what I'm doing wrong?
My code.....
use Fpdf\Fpdf as FPDF;
$current_x_position = 0;
$current_y_position = 0;
$total_y_per_page = 9;
$total_x_per_page = 3;
$pdf = new FPDF();
$pdf->SetMargins(0,0);
$pdf->SetAutoPageBreak(false);
$pdf->AddPage();
for($qty = 1; $qty <= 10; $qty++) {
label($current_x_position, $current_y_position, $pdf);
$current_y_position++;
if($current_y_position == $total_y_per_page) {
$current_x_position++;
$current_y_position = 0;
if($current_x_position == $total_x_per_page) {
$current_x_position = 0;
$current_y_position = 0;
$pdf->AddPage('P');
}
}
}
$pdf->Output();
function label($current_x_position, $current_y_position, $pdf) {
$left_margin = 7;
$top_margin = 15;
$label_width = 66;
$label_height = 30;
$current_x_position = $left_margin + ($label_width * $current_x_position);
$current_y_position = $top_margin + ($label_height * $current_y_position);
$pdf->Image('image.png', $current_x_position, $current_y_position+=1, $label_width, 10, 'png');
return;
}
?>
I think the problem stems from how x is being handled. It should be distinct from y. Why? Because x needs to be reset after every 3rd label is printed. Since it is only tested and incremented after 9 rows are printed, it will surely cause slueing. (Maybe that's an old-timey expression, used to indicate a program causes a new line because it is already past the column in which you want to print). Suggest you need to test x after every label print, so it can be reset to 0 when it reaches total_x_per_page (which I think really means total_x_per_row). The x test needs to be independent of the y test; it needs to be before the y test because you the columns will be complete before the rows.
In pseudo-ish code:
print a label
if the row is complete reset x, otherwise increase x
if the page is complete, reset y and x.
My experience with Fpdf is nil. My experience with (fighting) labels goes back decades :)
I have get the image pixel of an image at the particular point using getImagePixelColor.
$pixel = $image -> getImagePixelColor($x,$y);
Now I have modified that pixel's color using some method and now I want to set the new color of that pixel.
How can I do ?
There is a setColor function. But I got the pixel from the Imagick class. But the setColor function is in the ImagickPixel class. So how can I do it ?
ImagickPixel::setColor() is the correct function but it is also necessary to sync the pixel Iterator so your manipulations are written back to the image.
Here is a short yet (almost) complete example that reads an image file, manipulates each pixel, and dumps it to a browser:
$img = new Imagick('your_image.png');
$iterator = $img->getPixelIterator();
foreach ($iterator as $row=>$pixels) {
foreach ( $pixels as $col=>$pixel ){
$color = $pixel->getColor(); // values are 0-255
$alpha = $pixel->getColor(true); // values are 0.0-1.0
$r = $color['r'];
$g = $color['g'];
$b = $color['b'];
$a = $alpha['a'];
// manipulate r, g, b and a as necessary
//
// you could also read arbitrary pixels from
// another image with similar dimensions like so:
// $otherimg_pixel = $other_img->getImagePixelColor($col,$row);
// $other_color = $otherimg_pixel->getColor();
//
// then write them back into the iterator
// and sync it
$pixel->setColor("rgba($r,$g,$b,$a)");
}
$iterator->syncIterator();
}
header('Content-type: '.$img->getFormat());
echo $img->getimageblob();
->getImagePixelColor() returns an ImagickPixel object anyways, so $pixel->setColor(...); is all you need:
Ref: http://php.net/manual/en/imagick.getimagepixelcolor.php
Loads of answers on how to do it for a command line
convert /path/to/file/file.pdf[3] output.jpg
great... but what if I am using in memory processing, I am generating PDF with PDFlib and then output its buffer to a function that I want to generate jpg preview of selected page. How? My code :
[...]
$buf = $pdf->get_buffer();
//$buff is just a PDF stored in a string now.
$im = new Imagick();
$im->readimageblob($buf);
$im->setImageFormat("jpg");
$im->setimagecompressionquality(60);
$len = strlen($im);
header("Content-type: image/jpeg");
header("Content-Length: $len");
header("Content-Disposition: inline; filename=test.jpg");
echo $im;
This creates a jpeg but always returns last page of the PDF. I want to be able to choose which one will be converted. Is it doable without saving temporary files and using command line (exec('convert /path/to/file/file.pdf[3] output.jpg')) syntax?
Let me add that I tried
$im->readimageblob($buf[2]);
and it did not work :)
For the ones who is still searching for solution of reading specific page number from blob, please check this question Creating array populated by images from a PDF using PHP and ImageMagick
$img_array = array();
$im = new imagick();
$im->setResolution(150,150);
$im->readImageBlob($pdf_in);
$num_pages = $im->getNumberImages();
for($i = 0;$i < $num_pages; $i++)
{
$im->setIteratorIndex($i);
$im->setImageFormat('jpeg');
$img_array[$i] = $im->getImageBlob();
}
$im->destroy();
I'm loading the PDF binary into memory from Amazon S3 and then selecting the specific page I want using setIteratorIndex() followed by getImage()
function get_image_from_pdf($pdf_bytes, $page_num){
$im = new \Imagick();
$im->setResolution(150, 150);
$im->readImageBlob($pdf_bytes);
$im->setIteratorIndex($page_num);
$im = $im->getImage();
$im->setImageFormat('png');
return $im->getImageBlob();
}
version 3.0.1
being on the last image or first image in imagic object
$image_obj = new Imagick("test.pdf"); then you on last image in $image_obj
if you use
fp_pdf = fopen("test.pdf", 'rb');
$image_obj = new Imagick();
$image_obj -> readImageFile($fp_pdf);
then you on the first image in $image_obj
In second case to switch to last image you can do
fp_pdf = fopen("test.pdf", 'rb');
$image_obj = new Imagick();
$image_obj -> readImageFile($fp_pdf,2); // 2 can be any positive number?
then you on the last image in $image_obj
echo $image_obj->getNumberImages() // Returns the number of images in the object
then
if ($image_obj->hadPreviousImage)
$image_obj->previousImage() //Switch to the previous image in the object
}
or
if ($image_obj->hasNextImage()) {
$image_obj->nextImage()) //Switch to the next image in the object
}
e.g. if you have 6 images total and you need 4th then do from the end
$image_obj->previousImage()
$image_obj->previousImage()
$image_obj->setImageFormat("png");
header("Content-Type: image/png");
echo $image_obj;
EDIT: Another find is that you can
foreach($image_obj as $slides) {
echo "<br>".$Obj_img->getImageWidth();
//or wehatever you need to do.
}
EDIT 2: Very simple solution would be to use this function $image_obj->setIteratorIndex(4) count starts with zero.
It's not good news unfortunately, but I can definitively say that, as of time of writing, the ImageMagick (and PHP libraries) don't support the page notation that you're trying to use. (For people from the future finding this: I'm checking php-imagick-3.0.1 and imagemagick-6.6.0.4).
I'm trying to do the exact same thing as you, and I've just spent the last few hours trawling through the source, trying to figure out what it does and how it gets the pages, and it looks like it simply won't use it when reading from a stream (ie. the readBlob() call).
As such, I'm just going to be putting it in a temporary file and reading it from there instead. Not as elegant, but it'll work.