PHP Conference Japan 2024

Imagick::queryFontMetrics

(PECL imagick 2, PECL imagick 3)

Imagick::queryFontMetrics傳回代表字型度量的陣列

描述

public Imagick::queryFontMetrics(ImagickDraw $properties, string $text, bool $multiline = ?): array

傳回一個多維陣列,代表字型度量。

參數

properties

包含字型屬性的 ImagickDraw 物件

text

文字

multiline

多行參數。如果留空,則會自動偵測

傳回值

傳回一個多維陣列,代表字型度量。

錯誤/例外

發生錯誤時拋出 ImagickException。

範例

範例 #1 使用 Imagick::queryFontMetrics()

查詢文字的度量並將結果輸出到螢幕。

<?php
/* 建立新的 Imagick 物件 */
$im = new Imagick();

/* 建立 ImagickDraw 物件 */
$draw = new ImagickDraw();

/* 設定字型 */
$draw->setFont('/path/to/font.ttf');

/* 傾印字型度量,自動偵測多行 */
var_dump($im->queryFontMetrics($draw, "Hello World!"));
?>

新增註記

使用者貢獻的註記 8 個註記

23
stevepburgess at gmail dot com
9 年前
在花費相當多的時間研究各種字型的這些值之後,這是我對 fontMetrics 函數所給出值的理解。我正在 Centos 6.5 上使用 php 5.3 和 ImageMagick 6.5.4-7。

characterWidth 和 characterHeight
- 這些似乎與您為字型指定的大小有關,並且似乎不會因字型而異(在相同大小下)。因此,它們不是特別有用(至少對我而言)。它們並非字型將使用多少空間的可靠指標。

ascender
- 上行字元是字型中基準線以上的部分。它與字元無關 - 上行字元的值對於字型中的每個字元都相同。

descender
- 下行字元是字型中基準線以下的部分。它表示為負數。將上行字元和下行字元的絕對值相加,即可得到...

textHeight
- 這是字型可用的總高度。對於字型中的每個字元,無論其大小寫或字元佔用多少空間,都是相同的。這可用於在輸出段落等內容時確定行高。

textWidth
- 此值因字元而異,並且是字元的寬度。如果 boundingBox 沒有提供可用的值,這會很有用(請參閱下方的 boundingBox)。在逐個定位字元時 - 請勿使用 textWidth,而應使用 originX(請參閱下方)。

maxHorizontalAdvance
- 我恐怕還沒有完全弄清楚此用途。它對於字型中的每個字元都是相同的。對於大小為 67 的 Arial Italic 字型,該值為 89,比相同大小的 M 或 W 的進度報告寬得多。

boundingBox
- 這會傳回一個關聯陣列,描述包含該字元的矩形的四個點 (x1, y1, x2, y2)。這些值相對於原點(即您在影像中繪製字元的位置的座標)。傳回的矩形非常準確,並且完全包含列印字元的所有部分 - 但 boundingBox 僅適用於單個字元。它不會為多個字元提供準確的數字(至少以我的經驗來說)。繪製方塊時,您需要將「x」值「新增」到原點,並從原點「減去」「y」值。您不能依賴 SPACE 字元的 boundingBox。它會傳回 (0,0,0,0) 的 boundingBox。此時 textWidth(請參閱上方)會派上用場。

originX 和 originY
- 這些標題不準確。originX 和 originY 中傳回的值實際上是 advanceX 和 advanceY。這些值會給您下一個字元相對於目前字元的位置。

我希望這對您有所幫助。
12
jlong at carouselchecks dot com
11 年前
queryFontMetrics 的範例輸出

陣列
(
[characterWidth] => 9
[characterHeight] => 9
[ascender] => 9
[descender] => -2
[textWidth] => 71
[textHeight] => 10
[maxHorizontalAdvance] => 12
[boundingBox] => 陣列
(
[x1] => 0
[y1] => -2
[x2] => 6.890625
[y2] => 7
)

[originX] => 70
[originY] => 0
)
3
thok nojunk at spammail thok dot ca
13 年前
以下欄位構成我目前 PHP 5.2.1/Imagick 6.5.1 queryFontMetrics() 傳回陣列(一旦設定 setFontSize() 和 setFont())

characterWidth:最大字元(「em」)寬度
characterHeight:最大字元高度
ascender:字元上行的高度(例如 'b' 的直線部分)
descender:字元下行的高度(例如 'p' 的直線部分)
textWidth:以像素為單位的繪製文字寬度
textHeight:以像素為單位的繪製文字高度
maxHorizontalAdvance:從一個字元的開頭到下一個字元開頭的最大像素
boundingBox:x1、y1、x2、y2 邊界的陣列
originX、originY:?

originX 似乎遮蔽了 textWidth 欄位,而 originY 在我目前的研究中到目前為止都是零。

但是,如果您希望將文字置中或將其定位在邊緣,請使用 ImagickDraw::setGravity(int $gravity),其中 $gravity 是下列常數之一

Imagick::GRAVITY_NORTHWEST
Imagick::GRAVITY_NORTH
Imagick::GRAVITY_NORTHEAST
Imagick::GRAVITY_WEST
Imagick::GRAVITY_CENTER
Imagick::GRAVITY_EAST
Imagick::GRAVITY_SOUTHWEST
Imagick::GRAVITY_SOUTH
Imagick::GRAVITY_SOUTHEAST

對於更簡單的任務,使用 setGravity() 要容易得多。
2
george at sogetthis dot com
14 年前
直到包含 imagick 3.0.1,queryfontmetrics 都會根據 72x72 的影像解析度輸出大小資料。(請參閱錯誤:http://pecl.php.net/bugs/bug.php?id=19907

如果您設定了這個以外的解析度,並且正在使用 3.0.1 或更低版本,您需要將測量值按 YOUR_RESOLUTION / 72 的因數放大

例如,假設您已設定 300 的解析度
<?php
$im
= new Imagick();
$im->setResolution(300,300);

$draw = new ImagickDraw();
$draw->setFont('/path/to/arial.ttf');
$draw->setFontSize(72 * (300 / 72));
$data = $im->queryfontmetrics($draw, 'hello world');
var_dump($data);
?>

在 3.0.2 及以上版本,解決方案是在繪圖物件上設定與影像解析度相同的解析度。
<?php
$im
= new Imagick();
$im->setResolution(300,300);

$draw = new ImagickDraw();
$draw->setResolution(300,300);
$draw->setFont('/path/to/arial.ttf');
$draw->setFontSize(72);
$draw->setFillColor('#ff0000');
$data = $im->queryFontMetrics($draw, $string);

var_dump($data);
?>
0
SkepticaLee
10 年前
這些值與陣列描述符完全不符。如果您需要確切知道註解佔用了多少空間,請使用以下程式碼:

<?php
$text
= "Algbqdj";
$im = new Imagick ();
$draw = new ImagickDraw ();
$draw->setStrokeColor ("none");
$draw->setFont ("Arial");
$draw->setFontSize (96);
$draw->setTextAlignment (Imagick::ALIGN_LEFT);
$metrics = $im->queryFontMetrics ($draw, $text);
//以下是準確描述文字範圍及其繪製位置的值:
$baseline = $metrics['boundingBox']['y2'];
$textwidth = $metrics['textWidth'] + 2 * $metrics['boundingBox']['x1'];
$textheight = $metrics['textHeight'] + $metrics['descender'];
$draw->annotation (0, $baseline, $text);
$im->newImage ($textwidth, $textheight, "white");
$im->drawImage ($draw);
$draw->clear ();
$im->writeImage ("test.png");
$im->clear ();
?>

現在 test.png 檔案應包含幾乎完整的文字,且沒有邊框。這可能不適用於非常特殊的字體,但對於 Times New Roman 和 Arial 字體則可正常運作。
0
abcrdw at gmail dot com
13 年前
此腳本會在圖片中間列印浮水印。浮水印的寬度將取決於圖片的寬度。

<?php
// 建立新的 Imagick 物件
$objImage = new Imagick( 'path/to/image.jpg' );

// 取得影像的寬度和高度
$imgSize = $objImage->getImageGeometry();
$imgWidth = $imgSize['width'];
$imgHeight = $imgSize['height'];

// 建立新的文字物件
$objText = new ImagickDraw();

// 設定文字顏色
$objText->setFillColor( new ImagickPixel('grey') );

// 設定文字透明度:0 = 透明,1 = 不透明
$objText->setFillAlpha( 0.2 );

// 左上角將作為參考點
$objText->setGravity( Imagick::GRAVITY_NORTHWEST );

// 建立文字寬度和高度的陣列
$textProperties = array( 'textWidth' => 0 );

// 設定浮水印的所需寬度為影像寬度的 90%
$textDesiredWidth = intval( $imgWidth * 0.9 );

// 設定字型大小的初始值,將在下面的迴圈中增加
$fontSize = 0;

// 我們使用伺服器的網域名稱作為浮水印文字
$text = $_SERVER['SERVER_NAME'];

// 增加字型大小直到達到所需的寬度
while ( $textProperties['textWidth'] <= $textDesiredWidth ) {
$objText->setFontSize( $fontSize );
$textProperties = $objImage->queryFontMetrics( $objText, $text );
$fontSize++;
}

// 計算水平起始位置
$watermarkPosX = intval( ($imgWidth - $textProperties['textWidth']) / 2 );

// 計算垂直起始位置
$watermarkPosY = floor( ($imgHeight - $textProperties['textHeight']) / 2 );

// 將文字合成到影像上
$objImage->annotateImage( $objText, $watermarkPosX, $watermarkPosY, 0, $text );

// 瀏覽器必須知道這是 JPEG 影像,否則會顯示亂碼文字
header( 'Content-Type: image/jpeg' );

// 顯示影像
echo $objImage;
?>
0
Pete &#39;the Pete&#39; de Pijd
15 年前
您也可以使用 $imagickDraw()->setTextAlignmnent(Imagick::ALIGN_CENTER) 和 $imagickDraw->annotation(..) 來代替。
0
waage
16 年前
您可以使用此程式碼將文字置於方塊內置中。

<?php

$data
= "Hello world";

$text = new ImagickDraw();
$text->setFontSize(12);
$text->setFont("Arial");

$boxWidth = 210;

$im = new Imagick();

$fm = $im->queryFontMetrics($text, $data, false);

$textXLoc = ($boxWidth / 2) - ($fm["textWidth"] / 2);

?>

$textXLoc 現在是您需要提供給 annotateImage() 函數的起始位置。
To Top