php detect dpi of image in a pdf - php

I've tried a few tests using Imagick::getImageResolution on a PDF, and I can't figure out how to get the resolution (and colourspace) of an image embedded in a PDF. I've tried ripping the image out of the PDF, but during that process it seems the DPI is arbitrarily set to 72 not mater what I do.
I saw in 1564529 someone said DPI doesn't matter to a PDF, but that is not true (when an image is embedded in a PDF, several attributes about the image, like resolution, are defined in the PostScript). Is there a way in PHP (possibly with PSLib?) to figure out what the DPI of an embedded image is?

The 'dpi' of an image in PDF (or PostScript) is more nebulous than you may think. This is because it is possible to render the PDF at different scales, and so the actul dpi will vary.
You are correct that there is information regarding the scale factor of the image mebedded in the document. This is the Current Transformation Matrix, but it is not as simple as a single value, or even a single matrix.
The CTM maps co-ordinates into an idealised 'user space' which is nominally defined in points (72 per inch), but is infinitely subdivisible. When it comes to rendering, the 'user space' has a further transformation applied to scale it properly to the 'device space', the transformation is required because the device probably isn't 72 dpi.
You can find a much fuller explanation of this in the PDF Reference Manual, especially section 4.2.1 in the 1.7 reference.
So it would seem that all you need to do is take the declared /Width and /Height from the image dictionary, and apply the /Matrix to determine how big the image is in user space. Given that user space is effectively 72 dpi, then you would know how many inches the image was scaled to, how many pixels the image contains, and a simple division would give you the answer you want.
Indeed, in may cases this will work. However, one of the problems from your point of view, is that is possible, indeed common, to concatenate matrices to affect the current scaling, so simply looking at the matrix applied to an image won't give you the scale factor applied to that image, because something else may have already scaled the CTM. In addition PDF contains the 'UserUnit' kludge which allows a file to alter the default scaling of user space.
So the only way to work out the 'dpi' of an image is to interpret the page description to the point where the image is rendered, work out the total scaling at that point and from there figure out how much area the image covers. Then given the width and height of the image, work out its dpi.
In passing, here's a conundrum for you; its entirely possible to draw the same image multiple times in PDF, using the same image data. You only have to include the image data once. If I draw an image which is 100 pixels by 100 pixels and I draw it to cover one square inch, the resolution is 100 dpi. Now I draw the same image, but I scale it to cover half an inch. The resolution of the rendered image is now 200 dpi.
So what is the 'dpi of the image' ?

Hope this helps you:
http://forums.digitalpoint.com/showthread.php?t=884349

Related

Replacing detected object in a frame with an image.(imageProcessing)

Overview:
I am working on a video creation project. The technology I am using are: imageMagick, php, ffmpeg.
Current Status:
Currently the project is able to create videos using images and texts and few basic transitions. The way I am doing it is using imagemagick to create gif using input images(with transition effects in them) and then converting all gifs to videos and atlast concatenating the video together.
Next Move (My question):
I am now set to take it to the next level. So, what I am having is a video(1920x1080) with some white frames(1280x720) that keeps shifting in each frame. I want to replace those white frames appearing in some frames of the video with some images(1280x720) that I wish to use. Please see the image here and you will get an idea: These are just two frames from my video. If you can see carefully the images are shifting(white space is not constant).
Expectation:
So, I want to fill those white space with one of my own image. If the case would have been for only one frame I could have used ffmpeg to overlay image on the exact width and height. But here the white space is not fixed and keeps shifting in all the frames and there are a lot of frames. So, I am looking for something like opencv or some other technology that can be used for object detection in a video or in a set of frames and replace the detected area with some other image.
I just need a kick. So, if anyone has already worked on something like this just suggest me what technology can I use. Thanks in advance.
It all depends on exactly what you can assume :
If you can safely assume that your rectangle's boundary is never occluded (hidden) somehow, you can try finding the edges in your image (like OpenCV's Canny edge) and then look for rectangular shape (corners forming a warped rectangle, or the very popular Hough Lines).
If the rectangle you're looking for is always white, you can threshold the image in a colorspace like HSV to look for maximum value (the V in HSV ~ brightness) then rectangular shape search in a binary image.
If your corners are occluded sometimes you'll have to do some tweaking with your image, like morphological operations ("grow and contract" binary thresholded image), then Hough Lines could do the trick.
Note that this answer assumes that once you know where the rectangle is, "you're done", and you just have to overwrite the rectangle with custom content.
I also do not check for any time-continuity : you video frame might jump around based on the frame-by-frame appearance of rectangle. You'd have to include some knowledge about previous positions.

Scale HTML proportionally to fit exactly to PDF A4 size

I am using PHP, Mysql, jQuery. I have a webpage that is to be converted into high-res A4 size PDF: http://optisolbusiness.com/funeral_site/sample/index/id/255.
I have converted the HTML to PDF using wkhtmltopdf, which works great.
Here is the generated PDF http://optisolbusiness.com/Guru/Gurupdf/optisol.pdf. But the HTML is not fitting exactly to PDF size; There are spaces around the HTML in PDF. How to scale HTML to fit A4 PDF size 100%? Importantly the content inside the html (ie) text size, images width and height, background images also to be scaled proportionally.
Your background image is not exactly high-res, this won't look great in print.
I don't know wkhtmltopdf itself, but your body already has absolute dimensions set (in inches). This is probably the problem. Your body has a max size, the content has an absolute size too (given due to the background image pixel dimensions).
This is not a good starting point for html-to-print transformaions, and PDF is essentially print.
what to do (intermediate)
remove any size restrictions from body
wkhtml... has a switch called zoom, 1.5 should be an appropriate value to fill the page
use page-size a4
what to do (the "right" way)
remove size restrictions from body
build the background borders (the black ones) with html elements and css styling
refrain from defining "width" rules for those. You will only have to define a "width" once, all other widths should be set to "auto".
heights will prove troublesome, because divs are only as high as their content requires. But setting height: 100% does not respect border and margin sizes.
that yellow cross could be designed in css too, or a much higher resolution png/jpeg
Use only "real" dimensions. That means do not use pixels, use points, inches, or mm. You can use % values, but make sure those are % values of real dimensions (that means that at some point a parent element has a real dimension)
I'd say that you're always going to struggle to get this to be perfect. In my opinion you're better off writing the PDF directly rather than relying on a third party tool.
Consider looking into FPDF, an open-source PHP PDF writing library. Be warned, the website looks out of date, but the functionality works beautifully.
You can set the size of the body to the size of the page.. in case of A4 that is 210x297mm.
Btw: you should only be using width in percentage, otherwise wkhtmltopdf will have to try and convert it.
So make sure you use width: 100%; if you want it to fill all the room. ;)
BTW: If you want real high quality PDFs you will need to create them conforming to at least the PDF/X-3 standard. I don't think wkhtmltopdf does that tho.

Imagemagick Convert creating a very pixelated image

I use imagemagick to create thumbnails from images on my website using convert like so: convert -size 220x220 %s -resize 220 -profile '*' %s", $image, $thumb and this has worked great for a long time. Thousands of images have been processed and all the thumbnails look great ... except for one. For some reason this image produces a very ugly thumbnail and I can't figure out why.
Original image: http://i.imgur.com/fCbAN.jpg
Generated Thumbnail: http://i.imgur.com/MdLCs.jpg
Does anyone have any insight as to why this might happen with my convert code?
The thumbnail has been saved with very low quality (approximately 10-15, 99 being close to lossless). I think the question is, "why did that happen".
I can think of some reasons, but you will have to experiment. I assume the images you posted are the real images (not copies done converting e.g. PNG to JPG, I mean), and the command line is complete and describes the complete image workflow.
your ImageMagick setup attempts to keep estimated image quality. You do not set a quality explicitly (e.g. -quality 75), so the thumbnail gets the same quantizer setting as the source image. Suppose the source has a low quantizer, but you do not see it due to the high-frequency component (the image is "noisy" due to scanning). When resampling, the background loses its noise and becomes a smooth gradient, which was absent in the source. And a smooth gradient is hell on low quantizers. Try explicitly setting a quality factor (40 to 99, 40 is better compressed but chunkier, 99 is very high quality but bigger file).
there is some kind of interference between the resampler and the Moiré pattern that the scanner creates in the acquired image. This is less likely, because I see a "wavelength" of about 8 pixels which isn't at all uncommon, nor do I think that with so many images you acquired, none had approximately the same size and aspect ratio of this one; which in this scenario ought to have triggered the same behaviour. You say it didn't happen, so if this image isn't uncommon for size, aspect ratio, or source (e.g. one of the very few images scanned with a Scan-o-matic 600 scanner in the batch), this scenario becomes pretty unlikely. But if it is correct, then add a Gaussian blur before resizing and it ought to fix things: e.g. -blur 2x2.
there is bad juju in the file name, and for some reason this gets the ImageMagick wrapper to interpret a command of "set quantizer to its crappiest value". REALLY unlikely (if the interpret interprets a part of the filename as an option, it shouldn't interpret it as a filename, and the rest of the filename is no longer the true filename; resulting in a "File not found" error which we don't observe. All the same, if the original file name is something like "--progressive-swedish-music.jpg", try renaming it before thumbnailing.
I'm putting my money on option #1, anyway.
Another test which you could attempt is to run the same command from ImageMagick (command line) and not from PHP.

Dealing with different resolutions when building a gallery

I'm currently struggling with different resolutions when building my gallery-application. I've realized the problem: the photos can be in entierly different resolutions, or taken in landscape/portrait.
If I force the images to a fixed resolution - they are likely to be viewed as stretched.
If I don't: I can expect something like this (example of 6 different images with loose resolution, only fixed witdh):
When I'm actually looking for something like this (6 images with same resolution):
(these two galleries are actually running the same code)
I'd appreciate any suggestions on how to make this as pain-free as possible for the viewer. Thanks!
If you care anything about the artistic minded photographer, don't crop the image.
Resize them to a max-size (either width or height) to a specific measure, 400px, and place them each in a square div.
I think you're talking about image dimensions (not resolution, which is number of pixels in 1 inch).
To get th thing you want:
(1) Choose a width-height ratio that you want to show the image
(2) Cut of the extra portions of images to fit the ratio above (u can use GD library for PHP)
For example:
To make all portrait photos become landscape photos, cut off the top and the bottom sides. Rotating the portrait photos to become landscape is also a solution, but this won't be nice to viewers, coz they'll have to twist their necks to see the photos.
If you do not want to cut anything off, but still want to have as little whitespace on the screen as possible, you need to find an optimal arrangement of the images in unaltered form. This is a very difficult (NP-complete?) problem, but you can cut some corners if you want.
Looking at the images you posted, you could display five of them relatively cleanly together like this: put two portrait ones below each other, and add three landscape ones vertically stacked beside the portraits. If you scale them so that the height of two portraits is equal to the height of three landscapes, they will look more or less the same overall size.
You can find "pretty" screen-filling stacking methods for common aspect ratios of cameras, e.g. 16:9 and 4:3, and work off that assumption.
The gallery thumbnails have fixed dimensions (and fixed weight/height ratio), but source images have variable dimensions (and variable weight/height ratio). Here you have these options:
1- Stretch source images to thumbnail dimensions.
2- Add empty spaces (e.g. white) to the source images.
3- Crop extra spaces from the source images.
Demonstartion

Automatically align and resize 3 images into a small image with PHP?

I don't know if this is even possible with PHP, but I figured if it is, someone here will know how. I'm currently working on a project where users can customize a full body main avatar to be used throughout the site. There are a bunch of different face, hair, etc transparent png images that can be selected to make their custom avatar. I have this working great, but here is the hard part. I want to be able to use the face, hair, and beard (if male), and automatically create an 80x80 image that will be used as their small avatar for forum posts, etc.
There are a few obstacles with this. First, all of the images are 187x404 (big amounts of the image are transparent, the character body image is achieved by stacking the images, so a face image isn't actually that big). For this to work, the images would effectively have to be automatically cropped so that all of the extra space was removed and the actual face, hair, or beard part showed in the 80x80 spot.
The second issue is that some of the hair or beards (when placed on the full-size face image) would extend past the 80x80 and be chopped off. So the image would have to be pieced together at full size, and then resized to fit in 80x80.
I know the basic way of combining the 3 images into one (Combine 2-3 transparent PNG images on top of each other with PHP), but that is as far as I've gotten. If I'm crazy and this isn't possible then tell me. I'm probably way overcomplicating this, so if you see and obviously easier way to achieving this, I would love to hear it.
I think you need to decide first, cropping, resizing or a combination of both (cropping to a bigger square and resizing that).
Anyway, if you already have the images combined into one, all three options are easy to do in php. Take a look at imagecopyresampled().
The easiest way is just to always fit the face/hair/beard in the same area of the image. Then just crop that area out.
If you must, you can store extra data for each image specifying a rectangle in the image that must be visible in the small avatar. Then take the maximum extremities of these rectangles in all the images you compose, and crop+shrink that down to your small avatar size.
However, be aware that resizing PNG images by a few pixels (e.g. 83x83 -> 80x80) can substantially reduce the quality, particularly for images with lots of defined edges. This is because there are many pixels in the new image that are [nearly] evenly split between 4 pixels from the original image, and in images with sharp edges this leads to blurring.
So, shrinking an image to fit a portrait is not just difficult but also reduces quality. I'd cut off the beard instead!
I may be oversimplifying this, but can you try:
Keep track of max face size dimensions pre-compositing.
Output the composite image to a temporary file.
Crop square of largest values from step 1
Resize cropped image portion to 80 x 80

Categories