72DPI PNG to a 300DPI PDF + Cutting Cross - php

I have a flash which outputs a PNG file in 72DPI, I need to execute the following steps (not necessarily in that order) in order to make it ready for print:
Convert to 300DPI
Resize to 9x5 cm
Put cross (for cutting later) on it
Save as PDF - 300DPI
With my little of tutorial reading + knowledge in IM, I got this far:
1. convert -units PixelsPerInch IMAGE.PNG -resample 300 IMAGE_300DPI.png
2. convert IMAGE_300DPI.png -resize 1111x639 IMAGE_300DPI_correct_size.png
3. composite -gravity center IMAGE_300DPI_correct_size.png cross.png card_new_with_cross.png
4. convert card_new_with_cross.png card_new.pdf
When I execute stage #4 everything changes and gets enlarged as far as I can tell, any Ideas?
by the way - 2 files (sideA.png & cross.png) can be found at:
http://www.bikur.co.il/sideA.png <-- the image
http://www.bikur.co.il/cross.png <-- the `cross-
It would be great if someone can help me with it

DPI is a conversion factor, not a measurement. It's used to convert an image's intrinsic pixels into some display medium's pixel.
e.g. a 300 dpi printer has "pixels" that are 1/300 inches in size, while a 72dpi monitor has 1/72 inch sized pixels. A 100x100#72dpi image on a monitor would have to be printed out at about 417x417 printer pixels to have the same apparent size (300/72 = 4.16666)
So, whatever size your image is initially, to get a 9x5cm image # 300dpi, it'd have to be converted as follows:
9 x 5cm = 3.543 x 1.968 inches # 300dpi = 1063 x 591

Related

Recalculate the position of a larger object to re-align two different sized objects after rotation

I have 2 images I am placing on top of a 1080X1920 canvas.
One is a rectangle that is 800x400 and it is sitting on the 1080X1920 canvas with top left coordinates of x=140 and y=1200
Then I have another image that is the same size of the canvas 1080X1920, but also has a rectangle on it at the exact same coordinates as the first rectangle. I am overlaying this 1080X1920 image at x=0 and y=0 on the canvas so that the rectangle already in this image lines up perfectly with the rectangle that is already placed on the canvas.
My problem is, I need to apply a rotation to both of these and the black and red rectangles need to match up in positioning AFTER the rotation is applied. Could be any rotation, but let's say it is a 15 degree rotation.
When each element is placed on the canvas and then the 15 degree rotation is applied, the rectangles no longer align because of the difference in image size and the offset in rotation as they both rotate around the center point which looks to be my only option in this case.
So I am hoping to sort out a formula I can use that would rectify the positioning of the 1080X1920 image so that the object already embedded in that image lines up with separately overlaid image.
There are of course other ways to deal with this problem, but right now, they would make things quite a bit more difficult, so I wanted to see if this was possible to calculate first.
I have tried several ways to calculate this, but am not super mathematically proficient, so I am grasping at straws at best.
Oh and because I am not extremely mathematically proficient, any dumbing-down of mathematical terms is appreciated. ;)
Oh and possibly this post answers this question, but I can't wrap my head around whether or not it does, so if someone can let me know if it does, I will try harder to understand and apply it to my particular case.
How to recalculate the coordinates of a point after scaling and rotation?
Any rotation is done around a "center of rotation". You don't tell the centers you use, but they can be:
Center of the canvas.
Center of each image (middle point of its four corners),
Some corner.
Any other point.
If both rotations are not the same, then there's not possible match.
It seems you use the center of each image. Then, to match the second rectangle to the first one, after you rotate the first image you must do in this order:
Translate the second image so its center of rotation is exactly the
same as the center of rotation of the first image. The vector of translation is the coordinates difference for X,Y centers.
Rotate the second image with the same angle as the first image rotation.
This boils down to tracking where the original (0,0) points are on the two images after rotation.
Let's define the problem a bit cleaner:
red.png: 800x400
black.png: 1080X1920
rotate both by 15° (or θ = 15 * π/180) with rotate filter (assuming the actual values are within -90° and 90°)
how to place a rotated red.png on rotated black.png at the ORIGINAL top-left coordinates (x=140,y=120)
Consider 2 FFmpeg rotation commands:
ffmpeg red.png -vf rotate=15*PI/180:ow=hypot(iw\\,ih):oh=ow -frames:v 1 red_rotated.png
ffmpeg black.png -vf rotate=15*PI/180 -frames:v 1 black_rotated.png
Note that red_rotated.png is enlarged to inscribe the red rectangle while black_rotated.png maintains the same size. Now, the question is "where are the original top-left corner now?"
red_rotated.png:
0 < θ < π/2 cases: (xr,yr) = (h sin(θ), 0)
-π/2 < θ < 0 cases: (xr,yr) = (0, w sin(θ))
black_rotated.png: Same as red_rotated.png but now cropped to the original size
new size: ow = w cos(θ) + h sin(|θ|), oh = w sin(|θ|) + h cos(θ)
size delta: dw = (ow - w)/2, dh = (oh - h)/2
0 < θ < π/2 cases: (xb, yb) = (h sin(-θ) - dw, -dh)
-π/2 < θ < 0 cases: (xb, yb) = (-dw, w sin(θ) - dh)
Now, where is the insertion coordinate (x,y) = (140,120) on black_rotated.png:
rotate wrt the original corner: (x1,y1) = (x cos(θ) - y sin(θ), x sin(θ) + y cos(θ)
shift wrt the new black corner: (x2,y2) = (x1 + xb, y1 + yb)
shift wrt the new red corner: (x3,y3) = (x2 - xr, y2 - yr)
Accordingly overlaying red_rotated.png with the offset (x3,y3) onto black_rotated.png should get you the results you want.
Disclaimer: I have not verified my math, but this is should be a good starting point.

PNG processing WITHOUT Image Magick and imagefrompng()

I need to change each hue of yellow to blue, and each hue of dark gray to light gray in PNG images with transparency.
The problem is:
I can't use Photoshop, because I have 100 images, and I need to change hues many time.
I can't use Image Magick, because I need more sophisticated calculations, than '-fx' can do.
I can't use PHP imagefrompng(), because this nasty crap not works with a lot of my images,
even with all suggested fixes like:
$background = imagecolorallocate($png, 255, 255, 255);
// removing the black from the placeholder
imagecolortransparent($png, $background);
// turning off alpha blending (to ensure alpha channel information is preserved, rather than removed (blending with the rest of the image in the form of black))
imagealphablending($png, true);
// turning on alpha channel information saving (to ensure the full range of transparency is preserved)
imagesavealpha($png, true);
and so on. It works with some images, but not with others.
All I need is a PNG library (maybe not in PHP), that can give me red, green, blue and alpha component of a pixel at coordinates x, y, and then set this pixel after my calculations, eg:
$rgba = getrgba($image, $x, $y);
$rgba = my_function($rgba);
setrgba($image, $x, $y, $rgba);
Maybe you can suggest libraries in other languages, not only PHP?
If you don't mind using Python check out Pillow, specifically its PixelAccess class. These threads (1, 2) should be helpful and have some code examples.
Method 1
If you just want to get at the raw pixel values of R,G,B and Alpha without worrying about compression and encoding, use ImageMagick to convert your image to plain, uncompressed, unencoded binary and read it and process it to your heart's content.
So, if we make a 1x1 pixel PNG file with RGBA(0,64,255,0.5) to test with:
convert -size 1x1 xc:"rgba(0,64,255,0.5)" a.png
Now we can get ImageMagick to make a raw, RGBA file that you can read and process as you wish with whatever language you wish at whatever level of complexity that you wish:
convert a.png rgba:data.bin
and now we can look in that file:
xxd data.bin
Result
0000000: 0040 ff80 .#..
There you can see and read all the RGBA pixels. When you are finished, just do the opposite to get back a PNG - note that you must tell ImageMagick the size first since it cannot know this:
convert -size 1x1 rgba:data.bin new.png
Note that ImageMagick is quite a large package to install, and you can achieve much the same as the above with the much lighter-weight vips package:
vips VipsForeignSaveRaw a.png data.rgb
Method 2
Alternatively, if you want your data as uncompressed, human-readable ASCII, use the venerable NetPBM formats of PPM (Portable Pixmap) and PGM (Portable Greymap) - see NetPBM on Wikipedia.
Make a 4x1 image and write as PPM:
convert -size 4x1 xc:"rgba(0,64,255,0.1)" -compress none ppm:-
P3
4 1
65535
0 16448 65535 0 16448 65535 0 16448 65535 0 16448 65535
You can see the 4 repeated RGB values there hopefully. If you want it as a file, just change the ppm:- at the end with someFile.ppm.
Make same image again and extract Alpha channel to separate file:
convert -size 4x1 xc:"rgba(0,64,255,0.1)" -alpha extract -compress none pgm:-
P2
4 1
65535
6554 6554 6554 6554
Hopefully you can see that 6554 is 0.1 on a scale of 0-65535.
If you just want 8-bit data on any of the above, add in -depth 8.
Method 3
As Glenn suggests in the comments, another option is to omit the -compress none on Option 2 which will give you a very similar file format except the pixel data will be in binary, after the header which remains in ASCII. This is generally faster and smaller.

My php image server using Imagick produces much larger png8 files after cropping / scaling down

I'm trying to set up a simple PHP image server to allow me to add just large file for each of my images and then scale and crop them as needed. For my test file I start with a png8 exported via "save for web" from illustrator of size 2400 x 1200, which has a filesize of 21.6KB.
When I use Imagick's cropThumbnailImage function to reduce it to 600 x 600 the resulting file is 62.1KB (three times the size for a substantially smaller image). A 600 x 600 crop of the same image saved from illustrator clocks in at about 8.2KB. I can accept a modest file size increase for the added convenience, but an ~8x increase is just too much.
When saving the file I make sure to force the output to png8 so it doesn't default to a lossless png format, but other than that I'm clueless as to how to resolve it.
Here is my processing code:
//create working image
$image = new Imagick( $this->orig_file );
// Set Compression
$image->setImageCompressionQuality( 9 );
//scale image to height
$image->cropThumbnailImage ( $this->w, $this->h );
// strip extra data
$image->stripImage();
// save file
$image->writeImage( 'png8:'.$this->output_file );
Here are my test files:
Original Full scale image outputted by illustrator.
Cropped 600 x 600 image generated by imagick.
[EDIT: As per Mark's suggestion below I added the following changes]
// replacing cropThumbnailImage with:
$image->resizeImage(0, $this->h, imagick::FILTER_TRIANGLE, 1);
// crop
$start = ($image->getImageWidth() / 2) - ($this->w / 2);
$image->cropimage($this->w, $this->h, $start, 0);
// reduce colors to 20
$image->quantizeImage($this->q, 1, 0, true, false); // using 20 as $this->q
The end result goes from 62.1KB to 50.4KB, better but still over double the size of the fullsized image, and many times larger that the illustrator save for web version at that size.
600x600 image reduced to 20 colors and resized not thumbnailed
Your original image has 33 colours and weighs in at 22kB.
If you resize like this (albeit at the command line):
convert jabba.png -resize 600x600 -strip png8:result.png
the output file will be 6.6kB.
If you resize like I suggested with -scale:
convert jabba.png -scale 600x600 -strip png8:result.png
the output file will be 5.0kB.
If you retain -quality 9 in there, you will end up with > 25kB.

PHP/Imagick/PDFlib Flop Image Changes its Bit Depth

I am Having PNG Image And Trying To Flop (Mirror) by imagick function of php It Gets Flop Exactly But The
Base Image is In Format 24 Bit RGB
and after Convertion It Gets To
8 Bit Pallated
. So the Main Problem is that when I use to place both images in my pdflib pages one of the image(converted) displays curly....
Original Image
Output After Flop(Mirror) by Imagick and Rendered in PDFlib ->
My Code Is Simple ---->
$im = new Imagick($background_image);
$im->flopImage();
$im->writeimage($background_image."_flop.png");
Modified Date => 29 Oct 2013
Original Image -> Size 4.68 KB Bit Depth 32
Flopped Image -> Size 7.99 KB Bit Depth 64
Automatically Changes It's Properties
ORIGINAL
Converted
Imagick is using the smallest format possible to save the image. Saving in these formats all produce the same image but have the sizes:
Palette - 3.38kB
RGBA 32bit - 6.14kB
RGBA 64bit - 8.09kB
Saving to the smallest possible file is usually what people desire. However you can disable this in a couple of ways.
You can tell Imagick to use the same PNG format as the source image by setting the png:format option to png00. e.g.
$imagick = new Imagick(realpath("../images/FlopOriginal.png"));
$imagick->flopImage();
$imagick->setOption('png:format', 'png00');
$imagick->writeImage("../images/Flop.png");
The full options for png:format are png8, png24, png32, png48, png64, and png00.
Alternatively you can explicitly set the image format to use when saving the PNG file, through the png:bit-depth and png:color-type e.g.
$imagick = new Imagick(realpath("../images/FlopOriginal.png"));
$imagick->flopImage();
$imagick->setOption('png:bit-depth', '8');
$imagick->setOption('png:color-type', 6);
$imagick->writeImage("../images/Flop.png");
The color type values come from the libpng.h and are:
PNG_COLOR_TYPE_GRAY 0
PNG_COLOR_TYPE_RGB 2
PNG_COLOR_TYPE_PALETTE 3
PNG_COLOR_TYPE_GRAY_ALPHA 4
PNG_COLOR_TYPE_RGB_ALPHA 6
Both those methods produce a flopped image that is RGBA 32bit like the original image.

Imagemagick Crop command not giving perfect result

I am using Imagemagick for resizing and cropping image.
Test Image :
I need to re-size it for 300 x 320 frame for this first I am resizing the image and then cropping it and i am using the following commands:
exec("convert /uploadImagePath -thumbnail 300 /newImagePath");
exec("convert /newImagePath -gravity Center -crop 290x310+0+0 /newImagePath");
But it gives me following image
As you can see image is not complete. Where am I mistaken?
(Answer is updated, providing an illustrated example for -liquid-rescale further below now)
Your original image's dimensions are:
489 x 640 pixels
Your desired dimensions seem to be:
290 x 310 pixels
This cannot scale to these dimensions without either:
cropping (do not keep all areas of the intial image)
keeping desired width (give up desired height)
keeping desired height (give up desired width)
distortion (do not keep the aspect ratio when scaling)
padding (add more pixels to one or more edges)
removing pixels where it's not obvious ("liquid rescale" or "seam carving" -- see Wikipedia)
Your result shows '1.' (cropping), which you don't like. So you have options '2.' (keeping width), '3.' (keeping height), '4.' (distortion), '5.' (padding) and '6.' (seam carving) left to test.
'2.': Keeping desired Height
convert WPTgp.jpg -resize x310 keep-height.jpg
Resulting Image has dimensions of 237 x 310 pixels.
Keep Height....
(determine width automatically)
'3.': Keeping desired Width
convert WPTgp.jpg -resize 290x keep-width.jpg
Resulting Image has dimensions of 290 x 380 pixels.
Keep Width.....
(determine height automatically)
'4.': Distortion
convert WPTgp.jpg -resize 290x310\! distorted.jpg
Resulting Image has dimensions of 290 x 310 pixels.
Distorted......
(ignore aspect ratio -- distort image if required to fit dimensions)
'5.': Padding
convert WPTgp.jpg \
-resize 290x310 \
-gravity center \
-background orange \
-extent 290x310 \
padded.jpg
Resulting Image has dimensions of 290 x 310 pixels. (Orange background was added only to demonstrate that the 'extention' of the image did work.)
Padded.........
(keep aspect ratio -- extend image for desired dimensions)
'6.': Seam Carving
convert WPTgp.jpg -liquid-rescale 290x310\! liquid.jpg
The above would be the command you'd spontaneously derive from quick-reading the ImageMagick command options reference. However, it doesn't work well, and instead I used:
convert WPTgp.jpg -liquid-rescale 599x640\! -scale 290x310 liquid.jpg
convert WPTgp.jpg -liquid-rescale 599x640\! -scale 48.4% liquid.jpg
Further below is an explanation why I needed to modify it....
Liquid-rescaled
Sorry -- I cannot provide example picture right now; this requires the additional ImageMagick delegate liblqr (liquid rescaling library) to be installed, which I don't have at this moment) I've now had the opportunity to create a 'liquidly rescaled' version of the original image.
Caveats about Seam Carving / '-liquid-rescale':
As stated above, the last image is not the result of my originally proposed command, but of one of these two modified versions:
convert WPTgp.jpg -liquid-rescale 599x640\! -scale 290x310 liquid.jpg
convert WPTgp.jpg -liquid-rescale 599x640\! -scale 48.4% liquid.jpg
Remember, we have an original image of 489x610 pixels, which we are expected to scale to 290x310 pixels. But -liquid-rescale isn't good at rescaling in two dimensions at once -- it's designed to scale into one direction only (horizontal or vertical). If you try to do both at once, results may not be what you'd expect. Here is the result for the originally proposed command:
convert WPTgp.jpg -liquid-rescale 290x310\! liquid.jpg
LQR gone wrong
That's why I came up with the two modified commands which work in two steps:
First, apply liquid rescaling to the horizontal dimension only, expanding the original's width from 489 pixels to 599 pixels.
Second, apply 'normal' aspect-ratio-keeping scaling to the intermediate result to produce the final image.
Try:
$inputFile = "WPTgp.jpg";
exec("convert {$inputFile} -resize 290x310^ -gravity Center -crop 290x310+0+0 picCropped.png");

Categories