Can I Composite from right side with imagemagick? - php

In this normal case, when we need to composite a image on another image, we use :
exec("convert 1.jpg 2.jpg -geometry +0+0 -compose DstOver -composite result.jpg);
and 0,0 points are the start line in left site of picture.
I need to use my points from right side for example i have a jpg file with 500px height and 500px width and i need to composite image2 from 500,0 . its not good because if your image2 file has 100px in 100px height and width, your result hasn't any change in view.
my goal is compose from right side of image because my image2 has different width and height every time.
i mean i need compose from 3 and 4 point like picture.
I try Imagemagick place image in bottom right corner but this solution compose with SouthEast , SouthWest and ...
I need use my geometry size and points..
With image with fixed size i do not have any problem but i create text with imagemagick and it may with 1 charachter or more and in in this case my width of png text has different size.
Edit :
In fact i get text from input and with different length then compose with background picture like:
ok, i need compose with right corner of "Sample Text 2" like picture, not left like "Text1"
when i create text png file it may be created by different width and height .
(sorry i can't explain better and sorry for my bad english)

Edited
Ok, I am getting closer to understanding what you want, First observation is that if you specify -gravity then the offset in the geometry is relative to the gravity - it moves the overlaid image INWARDS from the gravity corner by the amount you specify in the geometry offset. So let's start by setting the gravity to NorthEast to put the overlay in the top-right corner:
convert background.jpg overlay.jpg -gravity northeast -composite out.jpg
Now let's get the width of the overlay and use it to calculate the geometry you require, assuming you want the overlaid image to have its right edge 50 pixels in from the background's right edge:
geom=$(convert overlay.jpg -print "+%[fx:w+50]+0" null:)
echo $geom # this is just to show what is happening - you don't need it
+150+0
convert background.jpg overlay.jpg -gravity northeast -geometry $geom -composite out.jpg
Of course you can do that in a single command like this:
convert background.jpg overlay.jpg -gravity northeast -geometry $(convert overlay.jpg -print "+%[fx:w+50]+0" null:) -composite out.jpg
Original Answer
I am sorry, but I still don't understand exactly what you are asking, so I will answer what I think you mean and maybe you can explain what is wrong with my understanding.
convert -size 500x500! xc:red background.jpg # make a big red background
convert -size 100x100! xc:blue overlay.jpg # make a smaller blue overlay
# place overlay on image at desired position
convert background.jpg overlay.jpg -geometry +360+40 -composite out.jpg

Related

Set image color to match background color php

I am using Imagemagick to work with images in php. I am no-wise in ImageMagick so could not do it. I have 2 Pictures, 1 is background and other one is above it. The one which is on top is of gray color png. While the background image can be any image. I want to set my top image's color to match the most color of background image.
For Example, this is a random background image which has beige/pink as its main color
and this is my top image
I want my above top image to change its color to match the most color of background image, as in the above image, it should be something like
Is it possible?
I don't feel like writing and debugging a load of PHP today, but can show you some techniques on the command line that you should be able to translate into PHP.
You can get the mean of the background image by resizing it to a single 1x1 pixel and then printing its value in RGB terms:
convert background.jpg -scale 1x1 -format "%[pixel:p{0,0}]" info:
srgb(219,199,164)
If I take that value and make a solid square out of it, you can see it is a beige colour like you suggest:
convert -size 100x100 xc:"srgb(219,199,164)" mean.png
You can probably use getImageChannelStatistics()
in PHP for that.
If I now take that colour, and make it the fill colour for tinting and apply a tint, I get this:
convert top.png -fill "srgb(219,199,164)" -tint 100% result.png
In PHP, you'd be looking at tintImage().
Something horrible has happened down the right side - I don't understand that, but if I extract the opacity from your top image and re-apply it to the result image, it goes away:
convert top.png -alpha extract alpha.pgm
convert top.png -fill "srgb(219,199,164)" -tint 100% alpha.pgm -compose copyopacity -composite result.png
I have solved it myself through these 2 lines of codes
exec("convert fabric.jpg -scale 1x1\! -format '%[pixel:u]' info:-", $a);
exec('convert arm-shadow.png -fuzz 10% -fill "'.$a[0].'" +opaque black -fill "'.$a[0].'" -opaque black foo.png');

ImageMagick: Composite images with text image, the outcome image invert the white background to black

I really need some help to understand the image channel problem,
I used ImageMagick to gen a text image with jpg 300 dpi RGB.
I then merge this image on the top of a background image(jpg 300 dpi CMYK 8bits/Channel).
I find the text image is normal when open this by default/photoshop, however when I merge to the background image, it have become inverting the color tone, black and white.
can anybody tell me what's wrong with the image?
please help I have tried couple of hours however still no answer
I'm using ImageMagick 6.7.9-10
This is the command I ran:
convert -background white -fill black \
-font 'Brandon_reg.otf' \
-pointsize 9 -size 445x -density 300 -gravity center\
caption:'Why this message become invert the black and white?' \
msg.jpg"
convert background.jpg msg.jpg \
-gravity center -composite output.jpg
please see this image

Crop image on angle

I'm currently looking for a way to crop an image, but on an angle.
I don't think I can just rotate the image first as the script is supplied with specific x,y coordinates of each corner.
So if you can imaging this, image is uploaded, 1280x720.
Along with the image it's supplied with x,x coordinates for the crop zone.
However the top left and top right coordinates will not have the same y position.
Heres an examples
Before
After
Any ideas ?
You'll still need to use trigonometry methods to rotate the image, but you can mimic a crop-at-an-angle by mixing opacity copying and trimming.
First. Create an Image Mask
If all the points are giving to you, and the image size is defined, simply draw the area that needs to be extract
WIDTH=819
HEIGHT=616
TOP_LEFT=669,117
TOP_RIGHT=784,155
BOTTOM_LEFT=544,495
BOTTOM_RIGHT=659,534
convert -size $WIDTHx$HEIGHT xc:black -fill white -stroke white \
-draw "polyline $TOP_LEFT $TOP_RIGHT $BOTTOM_RIGHT $BOTTOM_LEFT" \
mask.png
Masking and Background Removal
This method of masking will turn off the alpha-channel and set the background to transparent. When we compose the two images, the resulting image will only display what's within the area we defined in the mask. (note: you may need to adjust the -background to white, or transparent.)
convert source.jpg mask.png -alpha Off -compose CopyOpacity \
-composite -background transparent copyOpacity.png
Calculate Degree to Rotate
If you have two points on a square angle, you should be able to follow the atan method. Most language will have an atan2 function. Other trigonometry questions "Rotating a rectangle" & "How to calculate the angle between two points relative to the horizontal axis?"
DELTA_Y=$(($HEIGHT-155-534))
DELTA_X=$((784-659))
DEGREE=`awk "BEGIN { pi=4.0*atan2(1.0,1.0)+90; print atan2($DELTA_Y,$DELTA_X)*180/pi; }"`
convert copyOpacity.png -rotate $DEGREE -trim final.png
Luckily, you can do everything in one step.
#!/bin/bash
WIDTH=819
HEIGHT=616
TOP_LEFT=669,117
TOP_RIGHT=784,155
BOTTOM_LEFT=544,495
BOTTOM_RIGHT=659,534
DELTA_Y=$(($HEIGHT-155-534))
DELTA_X=$((784-659))
DEGREE=`awk "BEGIN { pi=4.0*atan2(1.0,1.0)+90; print atan2($DELTA_Y,$DELTA_X)*180/pi; }"`
convert source.jpg \( -size $WIDTHx$HEIGHT xc:black -fill white -stroke white \
-draw "polyline $TOP_LEFT $TOP_RIGHT $BOTTOM_RIGHT $BOTTOM_LEFT" \) \
-alpha Off -compose CopyOpacity -composite \
-background transparent -rotate $DEGREE -trim \
final.png

Trim image background but leave padding in Graphicsmagick

I assemble Graphicsmagick commands in php and then call them using exec(). I need to trim images but retain a padding of 20 pixels. So I want to do the following:
exec('gm convert input.jpg -trim -bordercolor white -border 20x20 output.jpg');
but use the color which was trimmed instead of white. How this can be achieved?
This works for me.
gm convert input.jpg -crop 1x1+0+0 corner.txt
color=`sed -e "s/.* #/#/" corner.txt`
gm convert input.jpg -trim -bordercolor $color -border 20x20 output.jpg
The txt format in GraphicsMagick has no header (unlike ImageMagick) so the (0,0) pixel is in the first line (actually the only line of a 1x1 image).
The corner.txt file for the 1x1 cropped image is simply this:
0,0: (255,255,255) #FFFFFF
It happened to be white in my test image, but it will be whatever the color of the (0,0) pixel.
It seems that this is currently not possible with GraphicsMagick (at the time of this writing: GM v1.4 beta).
In ImageMagick it can be done because IM provides an fx command to sample the color value of a given pixel:
convert myimage.png -format '%[fx:p{10,20}]' info:
This will return the color value of the pixel at position x=10, y=20. The output can then be used in subsequent IM commands to add a border of that color.

Get top left of pixel in image having alpha set 1 using imagick

I need to find the x coordinate of first pixel along with y coordinate having alpha set 1. I have a transparent image on which i have a black border rectangle. Now i need to find the rectangle's top and left.
For example, check image:
So i thought of, if somehow i can get first non transparent point in image i can get its coordinates and know about it.
Can it be done using Imagick in php. I read about pixelIterator, but how do i use it to do this? any suggestions or thoughts?
You could loopt trough all the pixels and use the Imagick::getImagePixelColor(x,y) function to read the color.
Three years later, and just for kicks, here are some thoughts on a way of approaching this with ImageMagick from the command line...
First, you can extract the transparency channel, using -alpha extract <filename>, but I don't really want the file so I can pipe it out to another convert command to threshold out anything where the alpha is not 1 (I assume a 16-bit quantisation, i.e. 65535=1) and then ask ImageMagick how it would trim that image to the smallest bounding box by using -format %# -write info:
convert rectangle.png -alpha extract png:- | convert - -threshold 65534 -format %# -write info: alpha.png
Output
91x118+80+81
That tells me the that the bounding box for the thresholded transparency is 91px wide by 118 pixels tall and it starts 80px across from the top left corner and most importantly that it starts 81 pixels down from the top - I now know the y coordinate is 81.
Whilst we don't actually need it to find the pixel you seek, it helps show what I am doing, so let me just draw that box so you can see it:
convert rectangle.png -stroke red -fill none -draw "rectangle 80,81 170,198" fyi.png
Now I can crop just the 81st line out of the image and look for the first white pixel with grep and exit as soon as I have found it.
convert alpha.png -crop x1+0+81 txt: | grep -m1 "#FFFFFF"
Output
147,0: (65535,65535,65535) #FFFFFF gray(255)
So, that tells me that the first white pixel is 147 across, so I know the x coordinate too. Therefore the pixel you seek is at 147,81.

Categories