I work on a designer tool where users can upload images, write text labels, etc... on an A4 paper. I am using canvas with KineticJS library, I have built the whole project on kineticJS. The result has to be printed in 300DPI size.
As I have many layers, most of them images loaded by the user, rotated, resized, colored, etc...
I have managed to save the 300dpi png file using these steps:
calculated what the designs 300DPI size is in pixels, got a variable
coef
set the stage size to be 300DPI (multiplied the actual width
and height with coef)
went through all the layers and resized all the objects to 300DPI size the same way as the stage size
used stage.toDataURL() with a callback function to send the raw data to php
saved the raw data in PHP into a PNG file
This all works fine except that all the export runs on the client machine, using the memory of the device and the resources of the browser. This results a couple of seconds (sometimes more then 10) of "browser not responding" and frozes a bit the whole device.
My question is that is there a better way to export it into PNG? I was thinking on two things:
1. to find a better solution inside javascript (using kineticjs)
2. send all the data to PHP (list of layers and attributes) and rebuild it in PHP, then export it. The problem with this one is that I dont know if it will be able to rebuild it exactly the same as in canvas. And rebuilding the text labels would be a bunch of work/time and difficulty: it has color, strike color, strike width, font size, opacity and the most important thing is that it uses Google Fonts which I dont know how could be used in PHP.
I'm really counting on your opinions! Thanks!
Related
I need to accept hundreds of pdfs at a time via PHP. I am storing these files on S3, so, file size will become a concern - not only for storing, but general handling. I'm finding the best way to reduce file size is conversion from PDF to PNG and back to PDF. A 15M file drops to 700kb. The problem is I'm losing certain fonts. Is there a way to ensure this doesn't happen? How do I ensure the process I use maintains the fonts in the original document? Is there some massive font library I can install?
from the command line I've tried...
Imagemagick
Ghostscript
pdftk
inkscape (real nice output)
They all work with varying levels of success, but each of them lose certain fonts - and not always the same ones.
Nope!
The .PDF format is an encapsulation of "graphics commands," such as "render the following text at position (X,Y) in the workspace using font Z."
When you "convert" such a file to any(!) "image file" format, you are in fact asking the PDF-engine to "carry out those graphics commands," producing a bitmap (a rectangular grid of pixels ...) as its only output.
Well, once you have done that, "you can never go back." The PDF-engine rendered its rectangular grid of pixels as best it could, and now, both it and the PDF-file that it consumed are gone, leaving you only with a rectangular grid of (output) pixels.
I have to create some nicely formatted charts (bar and 3D pie) from dynamic data using PHP 5.3 and for output as PDF report. The report is not to be rendered to the screen at all. I have made the charts using pChart2 as .png files and imported them using tcpdf. The system works, but the quality level is poor, rendering text as a graphic causes the font edges to be blurry etc. when printed. I tweaked the image size of the .PNG output, and it made some improvements but it increases the file size, and the text still looks blurry.
So what I am after is a library to create charts using PHP that can be exported to .svg or .eps format, so elements are drawn by the printer and render sharply for print. Using TCPDF I have imported our logos that are in .EPS format, and the difference between the images is quite marked.
I have seen there is a library called ezcomponents that i can give a try. But before I dive in, is there any advice on what to try before proceeding?
I have had reasonable success rendering the images on a canvas that is two to three times larger than what I ultimately need and then, once I'm finished, using the imagecopyrresampled() function to copy the large image onto a canvas with smaller dimensions, which I save as a png and add to the PDF file. The dithering is pretty good and curved lines, in particular, benefit greatly from this approach. Text might not benefit quite as much, but its worth trying, because it should require very few changes to your code to experiment with this approach.
I have an image which is essentially a star-burst effect. The color of the star-burst is white, and the background is transparent (PNG w/ Alpha). I randomly generate these star-bursts onto an HTML5 canvas at random locations, and at the same time, generate random Hue, Saturation, and Light (HSL) values. These could be RGB values, if this simplifies things.
The goal is to re-colorize the PNG for display on the HTML5 canvas based on the randomly generated HLS values before rendering it to the canvas.
I've read some other posts on StackOverflow and other sites, but the only solutions I've seen involve rendering it to the canvas, grabbing the coordinates for where the image is displaying, and modify the color on a pixel-by-pixel basis. In theory this could work, however some of the images may overlap slightly. Also if there is a background already present, then from what I understand, the background's color would also be modified which isn't much of a solutions for me either.
If this is out of the realm of what Canvases are capable of, as a fallback I suppose I would be okay with having images dynamically re-colored via PHP using GD2 or Imagick, or via the command-line via Gimp, ImageMagick or some other image library...
Thanks much!
-- OUTCOME --
Special thanks to #jing3142 for initial suggestion of off-screen canvas rendering, and #Jarrod for providing the vital piece I was missing: globalCompositeOperation = "source-in"
Here is a working implementation of the concept: http://jsfiddle.net/fwtW2/2/
Works in:
Chrome
Firefox
IE 9 (haven't tested other versions)
How about a second canvas that has the size of the image, place the image on that canvas, re-colour as required, extract re-coloured image and place at random on main canvas, re-colour image on second canvas using new HSL values, extract and randomly place on main canvas and repeat?
This may help as well https://developer.mozilla.org/en-US/docs/HTML/Canvas/Pixel_manipulation_with_canvas
I'm pretty sure you can just use the source-in globalCompositeOperation opertaion? No need to get all hardcore and crazy with vector images.
This code is where the magic happens:
var color = 'red';
ctx.fillStyle = color;
ctx.globalCompositeOperation = "source-in";
But yOu'd need to re-draw this to an offscreen canvas: You can do that like so
createBuffer = function(sizeW, sizeH)
{
buffer = document.createElement('buffer');
bufferCtx = buffer.getContext('2d');
buffer.width = sizeW;
buffer.height = sizeH;
}
then just draw your image to the offscreen canvas and apply the global composition.
Here’s how to easily recolor your starbursts just before rendering on canvas
Convert your starburst.png into a vector path! (I know, you will have to drag out Gimp/Illustrator for this one time—but it’s worth it!)
Starburst paths can have fills and the fills can be solid colors or even gradients—as fancy, random recoloring as you need!
Starburst paths can scale without the pixilation of raster images like .png’s.
Starburst paths can rotate to show diversity in your bursts--and even skew to represent a bit of 3d motion.
If you want to get fancy, you can even create “glowing” bursts by using shadows and blurs.
Starburst paths are faster to render than .png images—especially if you need to manipulate each .png before drawing.
I've been struggling for a while now trying to add a good looking background to my PDF created using the FPDF class. I tried a photoshop document based on international A4 paper, but this was too big. Also converting it from 300dpi to 72dpi (as it's said in the manual) is not good, it just looks pixelated now.
I found various settings on the net (~1062px width), but that's too wide and when testing with something that should match up just creates a pixelated version instead of a good background image.
Thanks in advance.
Remember that 'dpi' is just a conversion factor. it's not a measurement in-and-of-itself. The size of the background image will depend on what kind of medium you're planning on the PDF being displayed on.
If it's intended for screen display, which is generally 72-100dpi (let's split the difference and go with 86dpi). A4 paper is 210x297mm, or 8.27x11.7 inches, which means you need a background image of 711x1006 so it wouldn't get scaled.
If you're going for a 300dpi target, which is your average generic laser printer, then you'd need 2481x3510, and for 600dpi target, double again to 4962x7020
Lot of user opening my site in mobile,
Tell me which image type will load quickly in mobile device ,
jpg,gif,png ,
Which one is best ?
Go with PNG8 where possible and limit the color palette. Try to only use as many colors as strictly needed not more.
There are PNG tweaking tools which allow you to get rid of unnecessary chunks of that PNG. For more information on PNG chunks there is the PNG chunks specification found here.
http://www.libpng.org/pub/png/spec/1.2/PNG-Chunks.html
The tweaking tool I was talking about can be found here. It runs on Linux using wine as far as I have tested it.
http://entropymine.com/jason/tweakpng/
Additionally TinySVG is a pretty interesting format. SVG graphics allow lossless rescaling and because it is in fact a XML file you can modify it in a programmatic way.
EDIT: One note on JPEG graphics. If the file size exceeds 10kb save it progressive if it is under 10bk save it baseline. It is a small optimization for JPEGs.
There is no single "best" image type. The image that loads the quickest is the smallest one. But quick loading does you no good if your image is distorted and unidentifiable.
Pick image format base on the type of image you are trying to render:
JPEG is hands down the best for photos 99% of the time when you consider perceived image quality relative to file size; but JPEG's lossy compression algorithm relies on the existence of noise (lots of soft/subtle color transitions) and a lack of sharp lines/edges in the source image for the best effect. Never use JPEG for rasterized text!
PNG is the best option for rasterized images comprised of sharp edges and smooth/solid color blocks. Basically, anytime you need clean/lossless images (logos, icons, UI elements, text, etc.—anything but photos/paintings basically), you'd use PNG. It is also the only real option when you need alpha channel/partial transparency.
GIF is the only universally support animated image format, but aside from that I would just use PNG in most cases.
SVG is for vector images, but I'm not sure how many mobile browsers support it.
From a quick read, it seems that jpeg would be the best option. However, that is dependent on any specific needs you may have for some images (ie jpeg does not do transparent backgrounds, etc.)
Also, especially for a mobile site, if the images are frequently used parts of the website's layout (ie buttons, etc.) then using CSS Sprites is a good practice as it reduces the number of elements being downloaded to the user (of course, at the tradeoff that the image(s) which are downloaded are larger).