I'm trying to make a pdf with fpdf from a form in which the user introduces a file not neccesary a csv but with the structure of a csv.And I want the text to fill to the cell width because i have very long fields and others which are very short,so I want the text to do a line break and continue in the same cell without overlaying other element,so that i can have the large and short information in the same cell width.
EDIT:
I'm trying with multicell but i dont know why im having problems with setY because i dont know why it fails and the pdf cant open but when i commentes everything work fine only that the lines are at different height which is the work of setY
if ($file) {
$csv = [];
while (($data = fgetcsv($file)) !== FALSE) {
$csv[] = $data;
}
fclose($file);
$start_x = $pdf->GetX(); //initial x (start of column position)
$cell_width = 30; //define cell width
$cell_height = 10; //define cell height
foreach ($csv as $columna) {
foreach ($columna as $dato) {
$current_x = $pdf->GetX();
$currenty=$pdf->GetY();
//$cellWidth = $pdf->GetStringWidth(strtok(utf8_decode($dato),','));
//$salto = wordwrap(strtok(utf8_decode($dato), ','), 10, "\n", false);
$pdf->MultiCell($cell_width, $cell_height, strtok(utf8_decode($dato), ','), 1, 'C');
$current_x += $cell_width; //calculate position for next cell
$pdf->SetX($current_x);
$pdf->SetY($currenty);
}
//$pdf->Ln();
$current_x = $start_x; //set x to start_x (beginning of line)
$currenty += $cell_height;
$pdf->SetXY($current_x + $cell_width, $currenty);
}
}
}
Related
I dispatch php gd in my controller, here's the code
class getSmallImageController extends Controller
{
public function getImg(request $request)
{
// Get the image from local file. The image must be 300*200 size.
//change $img to your own path
$img_path = '/home/jonnyy/PhpstormProjects/zcapt/app/repository/Image/1.jpg';
$img = imagecreatefromjpeg($img_path);
$img_size = getimagesize($img_path);
if ($img_size[0] != 300 || $img_size[1] != 200)
die("image size must be 300*200");
//get value of authID from init.php
$response = app('App\Http\Controllers\initController')->index($request);
$authID = $response->getOriginalContent()['authID'];
// Calculate the diagonal coordinate for that square
$position_x_1 = DB::table('inits')
->select('x')
->where('authID', '=', $authID)
->inRandomOrder()
->first();
$position_y_1 = DB::table('inits')
->select('y')
->where('authID', '=', $authID)
->inRandomOrder()
->first();
// Create a small image with height 50 and width 50
$img_small = imagecreatetruecolor(50, 50);
// Copy one part of the large image (the image with size 300*200) to small part of image
imagecopy($img_small, $img, 0, 0, current($position_x_1), current($position_y_1), 50, 50);
// Change brightness of the picture
imagefilter($img_small, IMG_FILTER_BRIGHTNESS, 50);
$position_1 = 0;
$position_2 = 50;
// Adding some blur in to small picture
for ($i = 50; $i < 120; $i = $i + 6) {
imagerectangle($img_small, $position_1, $position_1, $position_2, $position_2, imagecolorallocatealpha($img_small, 255, 255, 255, $i));
$position_1 = $position_1 + 1;
$position_2 = $position_2 - 1;
}
// Set header in type jpg
;
// Generate image
header("Content-type: image/jpg");
// Generate image
imagejpeg($img_small);
// Release memory
imagedestroy($img_small);
;
imagedestroy($img);
}
}
Got this garbled
But When I dd() the last line of my code,
dd(imagedestroy($img))
return the picture I want.
By the way, the GD library works in another controller which I dispatched for.
That isn't the way the Laravel with MVC should work. As a dirty solution I believe that put exit; after imagedestroy() could work. Another option would be to save the image to disk and display to the user.
The following option is to save in memory and then send to the user. If your page/application isn't accessed too frequently, it can work well for you.
ob_start();
imagejpeg($img_small);
imagedestroy($img_small);
$image_data = ob_get_contents();
ob_end_clean();
$response = \Response::make($image_data, 200);
$response->header("Content-Type", "image/jpeg");
return $response;
I have a bmp file whose mime type is image/x-ms-bmp. I need to convert this into png or jpeg file. I have done below code :
$imagecreatefrombmp = $this->imagecreatefrombmp($imageContent);
ob_start();
imagejpeg($imagecreatefrombmp);
$imagedata = ob_get_contents();
ob_end_clean();
Copied imagecreatefrombmp as below :
public function imagecreatefrombmp($readContent)
{
/* // Load the image into a string
$file = fopen($p_sFile,"rb");
$read = fread($file,10);
while(!feof($file)&&($read<>""))
$read .= fread($file,1024); */
$temp = unpack("H*",$readContent);
$hex = $temp[1];
$header = substr($hex,0,108);
// Process the header
// Structure: http://www.fastgraph.com/help/bmp_header_format.html
if (substr($header,0,4)=="424d")
{
// Cut it in parts of 2 bytes
$header_parts = str_split($header,2);
// Get the width 4 bytes
$width = hexdec($header_parts[19].$header_parts[18]);
// Get the height 4 bytes
$height = hexdec($header_parts[23].$header_parts[22]);
// Unset the header params
unset($header_parts);
}
// Define starting X and Y
$x = 0;
$y = 1;
// Create newimage
$image = imagecreatetruecolor($width,$height);
// Grab the body from the image
$body = substr($hex,108);
// Calculate if padding at the end-line is needed
// Divided by two to keep overview.
// 1 byte = 2 HEX-chars
$body_size = (strlen($body)/2);
$header_size = ($width*$height);
// Use end-line padding? Only when needed
$usePadding = ($body_size>($header_size*3)+4);
// Using a for-loop with index-calculation instaid of str_split to avoid large memory consumption
// Calculate the next DWORD-position in the body
for ($i=0;$i<$body_size;$i+=3)
{
// Calculate line-ending and padding
if ($x>=$width)
{
// If padding needed, ignore image-padding
// Shift i to the ending of the current 32-bit-block
if ($usePadding)
$i += $width%4;
// Reset horizontal position
$x = 0;
// Raise the height-position (bottom-up)
$y++;
// Reached the image-height? Break the for-loop
if ($y>$height)
break;
}
// Calculation of the RGB-pixel (defined as BGR in image-data)
// Define $i_pos as absolute position in the body
$i_pos = $i*2;
$r = hexdec($body[$i_pos+4].$body[$i_pos+5]);
$g = hexdec($body[$i_pos+2].$body[$i_pos+3]);
$b = hexdec($body[$i_pos].$body[$i_pos+1]);
// Calculate and draw the pixel
$color = imagecolorallocate($image,$r,$g,$b);
imagesetpixel($image,$x,$height-$y,$color);
// Raise the horizontal position
$x++;
}
// Unset the body / free the memory
unset($body);
// Return image-object
return $image;
}
Its not creating the image correctly.
I need to render this image in a RTF file.
I just discovered this article http://jeffkreeftmeijer.com/2011/comparing-images-and-creating-image-diffs/
It is talking about using regular Ruby and ChunkyPNG to do image diffs.
In particular, the first code of doing a loop through all the pixels.
require 'chunky_png'
images = [
ChunkyPNG::Image.from_file('1.png'),
ChunkyPNG::Image.from_file('2.png')
]
diff = []
images.first.height.times do |y|
images.first.row(y).each_with_index do |pixel, x|
diff << [x,y] unless pixel == images.last[x,y]
end
end
puts "pixels (total): #{images.first.pixels.length}"
puts "pixels changed: #{diff.length}"
puts "pixels changed (%): #{(diff.length.to_f / images.first.pixels.length) * 100}%"
x, y = diff.map{ |xy| xy[0] }, diff.map{ |xy| xy[1] }
images.last.rect(x.min, y.min, x.max, y.max, ChunkyPNG::Color.rgb(0,255,0))
images.last.save('diff.png')
I wonder
a) what would be an ideal PHP equivalent of ChunkyPNG?
b) what would be the implementation of the same code in PHP?
You can do with Imagick extension. Imagick is a native php extension to create and modify images using the ImageMagick API.
Example Using Imagick::compareImages():
Compare images and display the reconstructed image.
<?php
$image1 = new imagick("image1.png");
$image2 = new imagick("image2.png");
$result = $image1->compareImages($image2, Imagick::METRIC_MEANSQUAREERROR);
$result[0]->setImageFormat("png");
header("Content-Type: image/png");
echo $result[0];
?>
OR
A PHP shell script to tell you if two images are visually different by comparing them pixel by pixel. If there's a difference, the script creates a third image - black background with the different pixels in green. Here two GD images are created from the input files, also a third GD image with black background to store the diff. Loop through all the pixels and compare them one by one. If one is different, write a green pixel at the same location of the diff image. [Source : http://www.phpied.com/image-diff/ ]
diff.php
<?php
/**
* Shell script to tell if two images are identical.
* If not, a third image is written - black background with the different pixels painted green
* Code partially inspired by and borrowed from http://pear.php.net/Image_Text test cases
*/
// check if there's enough input
if (empty($argv[1]) || empty($argv[2])) {
echo 'gimme at least two image filenames, please.', "\n";
echo 'e.g. "php idiff.php img1.png img2.png"';
echo "\n", 'third filename is the image diff, optional, default is "diffy.png"';
exit(1);
}
// create images
$i1 = #imagecreatefromstring(file_get_contents($argv[1]));
$i2 = #imagecreatefromstring(file_get_contents($argv[2]));
// check if we were given garbage
if (!$i1) {
echo $argv[1] . ' is not a valid image';
exit(1);
}
if (!$i2) {
echo $argv[2] . ' is not a valid image';
exit(1);
}
// dimensions of the first image
$sx1 = imagesx($i1);
$sy1 = imagesy($i1);
// compare dimensions
if ($sx1 !== imagesx($i2) || $sy1 !== imagesy($i2)) {
echo "The images are not even the same size";
exit(1);
}
// create a diff image
$diffi = imagecreatetruecolor($sx1, $sy1);
$green = imagecolorallocate($diffi, 0, 255, 0);
imagefill($diffi, 0, 0, imagecolorallocate($diffi, 0, 0, 0));
// increment this counter when encountering a pixel diff
$different_pixels = 0;
// loop x and y
for ($x = 0; $x < $sx1; $x++) {
for ($y = 0; $y < $sy1; $y++) {
$rgb1 = imagecolorat($i1, $x, $y);
$pix1 = imagecolorsforindex($i1, $rgb1);
$rgb2 = imagecolorat($i2, $x, $y);
$pix2 = imagecolorsforindex($i2, $rgb2);
if ($pix1 !== $pix2) { // different pixel
// increment and paint in the diff image
$different_pixels++;
imagesetpixel($diffi, $x, $y, $green);
}
}
}
if (!$different_pixels) {
echo "Image is the same";
exit(0);
} else {
if (empty($argv[3])) {
$argv[3] = 'diffy.png'; // default result filename
}
imagepng($diffi, $argv[3]);
$total = $sx1 * $sy1;
echo "$different_pixels/$total different pixels, or ", number_format(100 * $different_pixels / $total, 2), '%';
exit(1);
}
?>
Usage (Command line):
php diff.php img1.png img2.png result.png
Ok, so am working on a simple generator using jquery. A user enters a text of his/her choice, selects a font, font-color and font-size. All this properties are displayed on a separate div in real-time (live preview).
I now need to save the generated preview as a picture. For that, I use php GD library. All works fine but with some fonts, everything is just messed up.
In the first image, everything looks alright but the second image, the line height is just messed up.
This is my php script that am using to processes the properties
<?php
//Width and height of desired image
$width = 320;
$height= 320;
//Create an image with specified height and width
$main_img = ImageCreate($width, $height);
$mx = imagesx($main_img);
$my = imagesy($main_img);
//Capture values from form
$main_text = $_POST['rtext'];
$main_text_size = $_POST['rfsize'];
$color = $_POST['rcolor'];
$mt_f = $_POST['rfont'];
$main_text_x = ($mx/2);
// more code here
//wrap text if text too long
$words = explode(' ', $main_text);
$lines = array($words[0]);
$currentLine = 0;
for($i = 1; $i < count($words); $i++)
{
$lineSize = imagettfbbox($main_text_size, 0, $mt_f, $lines[$currentLine] . ' ' . $words[$i]);
if($lineSize[2] - $lineSize[0] < $mx)
{
$lines[$currentLine] .= ' ' . $words[$i];
}
else
{
$currentLine++;
$lines[$currentLine] = $words[$i];
}
}
$line_count = 1;
// Loop through the lines and place them on the image
foreach ($lines as $line)
{
$line_box = imagettfbbox($main_text_size, 0, $mt_f, "$line");
$line_width = $line_box[0]+$line_box[2];
$line_height = $line_box[1]-$line_box[7];
$line_margin = ($mx-$line_width)/2;
$line_y = (($line_height+12) * $line_count);
imagettftext($main_img, $main_text_size, 0, $line_margin, $line_y, $main_text_color, $mt_f, $line);
// Increment Y so the next line is below the previous line
$line_count ++;
}
header("Content-type: image/png");
//code to download the image
?>
Is there a way I can modify the part of the code where I wrap the text to accomodate all fonts? Like automatically calculate the line height based on the font?
Thanks, any help will be appreciated
I found a very useful class at phpclasses imagefittext.class.php http://www.phpclasses.org/browse/file/41869.html. I also found an example script that is implemented using the class http://www.phpclasses.org/browse/file/41870.html. This is exactly what I wanted.
Worked Perfectly!!!1
This one might be a little confusing. I'm using AMCharts with rails. Amcharts comes with a PHP script to export images called "export.php"
I'm trying to figure out how to take the code in export.php and put it into a controller.
Here is the code:
<?php
// amcharts.com export to image utility
// set image type (gif/png/jpeg)
$imgtype = 'jpeg';
// set image quality (from 0 to 100, not applicable to gif)
$imgquality = 100;
// get data from $_POST or $_GET ?
$data = &$_POST;
// get image dimensions
$width = (int) $data['width'];
$height = (int) $data['height'];
// create image object
$img = imagecreatetruecolor($width, $height);
// populate image with pixels
for ($y = 0; $y < $height; $y++) {
// innitialize
$x = 0;
// get row data
$row = explode(',', $data['r'.$y]);
// place row pixels
$cnt = sizeof($row);
for ($r = 0; $r < $cnt; $r++) {
// get pixel(s) data
$pixel = explode(':', $row[$r]);
// get color
$pixel[0] = str_pad($pixel[0], 6, '0', STR_PAD_LEFT);
$cr = hexdec(substr($pixel[0], 0, 2));
$cg = hexdec(substr($pixel[0], 2, 2));
$cb = hexdec(substr($pixel[0], 4, 2));
// allocate color
$color = imagecolorallocate($img, $cr, $cg, $cb);
// place repeating pixels
$repeat = isset($pixel[1]) ? (int) $pixel[1] : 1;
for ($c = 0; $c < $repeat; $c++) {
// place pixel
imagesetpixel($img, $x, $y, $color);
// iterate column
$x++;
}
}
}
// set proper content type
header('Content-type: image/'.$imgtype);
header('Content-Disposition: attachment; filename="chart.'.$imgtype.'"');
// stream image
$function = 'image'.$imgtype;
if ($imgtype == 'gif') {
$function($img);
}
else {
$function($img, null, $imgquality);
}
// destroy
imagedestroy($img);
?>
There are some versions in existence in a thread I found here: http://www.amcharts.com/forum/viewtopic.php?id=341
But I have a feeling the PHP code above has changed since then - because neither implementation worked for me.
What this code more or less dose is grabs the informations, that were sent to the script (POST).
The informations include the height and width of the picture and the RGB values of every pixel. The script draws every pixel and sends the images at the end to the client.
You can use Rmagick's method to draw a pixel. This will give you the same result.
The incomming post data looks like this:
height = number -> cast to int
width = number -> cast to int
// first row with a repeating part of R:G:B,R:G:B,... (n = width)
r0 = 255:0:0,150:120:0,77:88:99,...
r1 = ...
.
.
r100 = ... -> the row count is the height - 1
Actually, I found a discussion about speeding up pixel by pixel drawing.
So apparently I was running into other errors which made me think the already existing code didnt work. However, the code on the thread I linked to in the original question does in fact work!