phppup Posted January 23, 2020 Share Posted January 23, 2020 I want to watermark a simple TEXT line on some images (ie: "SAMPLE") I have successfully created a working code and using imagettftext and the PHP manual, I have summized that the coordinates 0,0 will essentially place the beginning of the text at the top left corner of my image. This would remain the same regardless of the image size or shape. Are there coordinates that will consistently designate the lower-right corner? Do the coordinates change for horizontals and verticals; large files and small? Quote Link to comment Share on other sites More sharing options...
requinix Posted January 23, 2020 Share Posted January 23, 2020 The coordinates are pixel offsets. 0,0 is the top-left corner, then you count pixels towards the right and bottom. Not magic. So the answer to what the coordinates are for the bottom-right is to find out the dimensions of the image. When you figure that out and try to write the text, you'll probably find out that it didn't write. Except it did. You just can't see it. Try moving the offset something like 20 pixels up and right from the corner and see what happens. Quote Link to comment Share on other sites More sharing options...
gizmola Posted January 23, 2020 Share Posted January 23, 2020 Along the lines of what requinix stated, here are some functions you'll need to calculate where to place your text: imagefontwidth imagefontheight imagesx imagesy To get the length of the string, you need to find imagefontwidth($font) * strlen($yourtext). Hopefully it's fairly obvious that your x,y coordinate for writing the string is going to be: y = imagesy() - (imagefontheight + padding) x = imagesx() - (imagefontwidth($font) * strlen($yourtext) + padding) Quote Link to comment Share on other sites More sharing options...
requinix Posted January 23, 2020 Share Posted January 23, 2020 Note that is for the fixed-width fonts that GD supports out of the box. With TTF fonts, character widths vary so calculating the right offset is a bit harder. 1 Quote Link to comment Share on other sites More sharing options...
Barand Posted January 23, 2020 Share Posted January 23, 2020 (edited) A few notes about text bounding boxes which, I hope, will help in precise placement of your text. Suppose I have the text string "The lazy fox" which I want to display using 150pt Vivaldi . My image is 4896 x 3672 and I want the text placed at the bottom right but 250 pixels from the edges of the image. $box = imagettfbbox(150,0,'c:/windows/fonts/vivaldii.ttf','The lazy fox'); gives this array of coordinates of the four corners $box = Array ( [0] => 23 [1] => 55 [2] => 871 [3] => 55 [4] => 871 [5] => -140 [6] => 23 [7] => -140 ) You may wonder why it can't just give a rectangle from (0,0) to (width, height) to make sizing simple, but there is extra information to be extracted from the array Text width = (871 - 23) = 848 Text height = 55 - (-140) = 195 The baseline will be 140px from the top The text is offset 23 px to the right. My text, therefore, will be in a rectangle 848 x 195 positioned 250 px from right and bottom edges. The top left x coord of the rectangle will be (4896 - 250 - 848) = 3798 and top left y coord will be (3672 - 250 - 195) = 3227. However, to land the text precisely into this area we position it on the baseline and at the required x offset, ie (3798 - 23 , 3227 + 140) = (3775, 3367). I use a simple custom function to assist with this process function metrics($font, $fsize, $str) { $box = imagettfbbox($fsize, 0, $font, $str); $ht = abs($box[5] - $box[1]); $wd = abs($box[4] - $box[0]); $base = -$box[5]; $tx = -$box[0]; return [ 'width' => $wd, 'height' => $ht, 'ascent' => $base, 'offsetx' => $tx ]; } $box = metrics ('c:/windows/fonts/vivaldii.ttf', 150, 'The lazy fox'); $box = Array ( [width] => 848 [height] => 195 [ascent] => 140 [offsetx] => -23 ) Edited January 23, 2020 by Barand 3 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.