Pengukuran teks gambar PHP GD

Saya mencoba menulis skrip yang menghasilkan gambar PNG dari teks, ukuran, dan font yang ada di argumen $_GET, tetapi saya tidak tahu cara membuat ukuran gambar pas dengan teks. Saya sudah menggunakan imagettfbox:

$widthPx = abs($ttfBox[2] - $ttfBox[0]);
$heightPx = abs($ttfBox[1] - $ttfBox[7]);

yang mungkin memberi saya pengukuran yang benar tetapi ketika saya menggambar teks, teksnya menjadi sedikit keluar batas. Misalnya jika saya mencoba menggambar "a" menggunakan arial.ttf setidaknya 5 piksel di luar batas. Apakah ada cara untuk menggambar teks dengan font apa pun yang sesuai dengan gambar tanpa mengujinya?

$text = $_GET["text"];

$cmToPixel = 15.0;

$sizeCm = floatval($_GET["sizeCm"]);
$sizePx = $cmToPixel * $sizeCm;
$fontFile = "fonts/".pathinfo($_GET["font"])["filename"].".".pathinfo($_GET["font"])["extension"];

if(!file_exists($fontFile)){
    die;
}
$ttfBox = imagettfbbox($sizePx, 0, $fontFile, $text);

$widthPx = abs($ttfBox[2] - $ttfBox[0]);
$heightPx = abs($ttfBox[1] - $ttfBox[7]);

$image = ImageCreate($widthPx, $heightPx);

$x = $ttfBox[0] + (imagesx($image)-$ttfBox[4] )/ 2 - 0;
$y = $ttfBox[1] + (imagesy($image) / 2) - ($ttfBox[5] / 2) - 5;

ImageRectangle($image,0,0,imagesx($image),imagesy($image), ImageColorAllocate($image,255,255,255));
imagettftext($image, $sizePx,0,$x,$y, ImageColorAllocate($image, 0, 0, 0), $fontFile, $text);

header("Content-Type: image/png");
ImagePng($image);
ImageDestroy($image);

person user1563232    schedule 07.02.2015    source sumber
comment
Pernahkah Anda melihat contoh yang diberikan bersama manual ini? Mereka mungkin membantu: imagettfbbox — Memberikan kotak pembatas teks menggunakan font TrueType   -  person Ryan Vincent    schedule 08.02.2015
comment
Saya sudah melihat semua contohnya, sepertinya saya harus memangkas gambar dengan menguji warna piksel, karena keluaran teksnya terlalu tidak akurat. Setiap teks mempunyai offset yang berbeda-beda ketika saya menggambarnya sehingga selalu di luar batas.   -  person user1563232    schedule 08.02.2015
comment
Bisakah kode yang Anda gunakan diposkan agar kami dapat bereksperimen dengannya?   -  person Ryan Vincent    schedule 08.02.2015
comment
Saya menambahkan kode, saya mencoba berbagai hal untuk koordinat x dan y teks, tidak terlalu membuat perbedaan. Mungkin lebih baik mencoba pendekatan berbeda seperti memangkas gambar berdasarkan warna piksel.   -  person user1563232    schedule 08.02.2015
comment
Masalahnya adalah GD tidak menggunakan 'metrik font' yang memberikan nilai dan offset dari 'garis dasar' karakter. Imagack memang menggunakan nilai-nilai ini sehingga lebih akurat. Pada dasarnya, di GD, Anda mendapatkan beberapa faktor 'fudge' yang bergantung pada 'keluarga font'. Membuat 'imagick' mengerjakan 'windows' adalah 'kurang menyenangkan' dan saya belum berhasil.   -  person Ryan Vincent    schedule 08.02.2015


Jawaban (1)


Perhitungan Anda dari kotak pembatas tidak aktif. Ini bekerja:

<?php
/*-
 * $MirOS: www/mk/ttf2png,v 1.8 2016/11/02 16:16:26 tg Exp $
 *-
 * Copyright (c) 2009, 2016
 *  mirabilos <[email protected]>
 *
 * Provided that these terms and disclaimer and all copyright notices
 * are retained or reproduced in an accompanying document, permission
 * is granted to deal in this work without restriction, including un-
 * limited rights to use, publicly perform, distribute, sell, modify,
 * merge, give away, or sublicence.
 *
 * This work is provided "AS IS" and WITHOUT WARRANTY of any kind, to
 * the utmost extent permitted by applicable law, neither express nor
 * implied; without malicious intent or gross negligence. In no event
 * may a licensor, author or contributor be held liable for indirect,
 * direct, other damage, loss, or other issues arising in any way out
 * of dealing in the work, even if advised of the possibility of such
 * damage or existence of a defect, except proven that it results out
 * of said person's immediate fault when using the work as intended.
 *-
 * Syntax:
 *  php ttf2png [text [size [/path/to/font.ttf]]] >out.png
 */

if (!function_exists('gd_info'))
    die("Install php5-gd first.");
$gd = gd_info();
if ($gd["FreeType Support"] == false)
    die("Compile php5-gd with FreeType 2 support.");


$font = "/usr/src/www/files/FNT/GenI102.ttf";
$fontsize = 30;
$text = "EINVAL";

if (isset($argv[1]))
    $text = $argv[1];
if (isset($argv[2]))
    $fontsize = $argv[2];
if (isset($argv[3]))
    $font = $argv[3];


// Get bounding box
$bbox = imageftbbox($fontsize, 0, $font, $text);
// Transform coordinates into width+height and position
$ascender = abs($bbox[7]);
$descender = abs($bbox[1]);
$size_w = abs($bbox[0]) + abs($bbox[2]);
$size_h = $ascender + $descender;
$x = -$bbox[0];
$y = $ascender;

// Create image
$im = imagecreatetruecolor($size_w, $size_h);
// Allocate colours
$bgcol = imagecolorallocate($im, 0x24, 0x24, 0x24);
$fgcol = imagecolorallocate($im, 0xFF, 0xFF, 0xFF);

// Fill image with background colour
imagefilledrectangle($im, 0, 0, $size_w - 1, $size_h - 1, $bgcol);
// Render text into image
imagefttext($im, $fontsize, 0, $x, $y, $fgcol, $font, $text);

// Convert true colour image (needed for above) to palette image
imagetruecolortopalette($im, FALSE, 256);

// Output created image
imagepng($im, NULL, 9);

exit(0);

Jika Anda menulis beberapa string pada baris yang sama dan perlu menghitung tinggi total dan offset garis, maka itu adalah maksimum dari semua ascender ditambah maksimum semua descender, dan $y untuk semua imagefttext memerlukannya garisnya juga merupakan maksimum dari semua ascender.

person mirabilos    schedule 02.11.2016
comment
@MarcielFonseca itu PNG, simpan ke file atau kirimkan melalui xloadimage stdin atau penampil gambar lain yang sesuai. Biasanya alat Unix membuang hasilnya ke stdout, agar dapat digunakan sebagai filter melalui pipa. - person mirabilos; 25.03.2017