Tự động tạo character map từ file font

Hàm bên dưới sẽ có chức năng tự động tạo ra hình ảnh bao gồm các ký tự nhập vào sẵn, mục đích của hàm này dùng để tạo character map demo cho một font chữ bất kỳ.

function hocwp_generate_font_character_map( $font_path, $font_size = 12, $chars = array(), $output = '*.png|9', $colors = array(), $padding = 8 ) {
	$font_path = realpath( $font_path );
	if ( $font_path === false || ! is_readable( $font_path ) ) {
		return false;
	}
	$path_info      = pathinfo( $font_path );
	$font_file_name = basename( $font_path, '.' . $path_info['extension'] );
	if ( ! is_int( $font_size ) ) {
		$font_size = 12;
	}
	if ( ! is_array( $chars ) || empty( $chars ) ) {
		$chars  = 'abcdefjhijklmnopqrstuvwxyz';
		$chars  = str_split( $chars );
		$string = 'ABCDEFJHIJKLMNOPQRSTUVWXYZ';
		$string = str_split( $string );
		$chars  = array_merge( $chars, $string );
		$string = '1234567890';
		$string = str_split( $string );
		$chars  = array_merge( $chars, $string );
		$string = '`-=[]\\;\',./';
		$string = str_split( $string );
		$chars  = array_merge( $chars, $string );
		$string = '~!@#$%^&*()_+{}|:"<>?';
		$string = str_split( $string );
		$chars  = array_merge( $chars, $string );
	}
	$textColor       = isset( $colors['text'] ) ? $colors['text'] : array( 0, 0, 0 );
	$borderColor     = isset( $colors['border'] ) ? $colors['border'] : array( 210, 210, 210 );
	$backgroundColor = isset( $colors['background'] ) ? $colors['background'] : array( 255, 255, 255 );
	$indexColor      = isset( $colors['index'] ) ? $colors['index'] : $borderColor;
	$data            = array();
	$charWidths      = array();
	$charHeights     = array();
	$i               = 0;
	foreach ( $chars as $char ) {
		$bbox          = imagettfbbox( $font_size, 0, $font_path, $char );
		$data[ $i ]    = array(
			'string'     => $char,
			'code_point' => $char,
			'ascent'     => abs( $bbox[7] ),
			'descent'    => abs( $bbox[1] ),
			'width'      => abs( $bbox[0] ) + abs( $bbox[2] ),
			'height'     => abs( $bbox[7] ) + abs( $bbox[1] )
		);
		$charWidths[]  = $data[ $i ]['width'];
		$charHeights[] = $data[ $i ]['height'];
		$i ++;
	}
	$total       = count( $chars );
	$row         = 13;
	$column      = ceil( $total / $row );
	$cellWidth   = ceil( ( ( max( $charWidths ) + min( $charWidths ) ) / 2 ) * 2 ) + $padding * 2;
	$cellHeight  = ceil( ( ( max( $charHeights ) + min( $charHeights ) ) / 2 ) * 2 ) + $padding * 2;
	$imageWidth  = $cellWidth * $row + 1;
	$imageHeight = $cellHeight * $column + 1;
	$image       = @imagecreatetruecolor( $imageWidth, $imageHeight );
	if ( ! $image ) {
		return false;
	}
	imageantialias( $image, true );
	$colorText       = imagecolorallocate( $image, $textColor[0], $textColor[1], $textColor[2] );
	$colorBorder     = imagecolorallocate( $image, $borderColor[0], $borderColor[1], $borderColor[2] );
	$colorBackground = imagecolorallocate( $image, $backgroundColor[0], $backgroundColor[1], $backgroundColor[2] );
	$colorIndex      = imagecolorallocate( $image, $indexColor[0], $indexColor[1], $indexColor[2] );
	imagefill( $image, 0, 0, $colorBackground );
	$indexSize = 1;
	for ( $i = 1; $i <= 5; $i ++ ) {
		$imageFontWidth = imagefontwidth( $i ) * 8;
		if ( $cellWidth > $imageFontWidth ) {
			$indexSize = $i;
		}
	}
	for ( $i = 0; $i <= $row; $i ++ ) {
		imageline( $image, $i * $cellWidth, 0, $i * $cellWidth, $imageHeight, $colorBorder );
	}
	for ( $j = 0; $j <= $column; $j ++ ) {
		imageline( $image, 0, $j * $cellHeight, $imageWidth, $j * $cellHeight, $colorBorder );
	}
	$k = 0;
	for ( $j = 0; $j < $column; $j ++ ) {
		for ( $i = 0; $i < $row; $i ++ ) {
			if ( ! isset( $data[ $k ] ) ) {
				break;
			}
			$x      = $i * $cellWidth + 3;
			$y      = $j * $cellHeight + 1;
			$string = $data[ $k ]['code_point'];
			imagestring( $image, $indexSize, $x, $y, $string, $colorIndex );
			$x    = $i * $cellWidth + ceil( ( $cellWidth - $data[ $k ]['width'] ) / 2 );
			$y    = $j * $cellHeight + ceil( ( $cellHeight - $data[ $k ]['height'] ) / 2 ) + $data[ $k ]['ascent'];
			$text = $data[ $k ]['string'];
			imagettftext( $image, $font_size, 0, $x, $y, $colorText, $font_path, $text );
			$k ++;
		}
	}
	$file_name = null;
	$quality   = null;
	if ( strpos( $output, '|' ) !== false ) {
		list( $file, $quality ) = explode( '|', trim( $output ), 2 );
	} else {
		$file = trim( $output );
	}
	if ( strpos( $file, '.' ) !== false ) {
		$path_info = pathinfo( $file );
		$file_type = $path_info['extension'];
		$file_name = substr( $path_info['basename'], 0, strrpos( $path_info['basename'], '.' ) );
		if ( $file_name == '*' ) {
			$file_name = $path_info['dirname'] . '/' . $font_file_name;
		} else {
			$file_name = $file;
		}
	} else {
		$file_type = $file;
	}
	switch ( strtolower( $file_type ) ) {
		case 'gif':
			if ( is_null( $file_name ) ) {
				header( 'Content-Disposition: inline;filename=' . $font_file_name . '.' . $file_type );
				header( 'Content-Type: image/gif' );
				imagegif( $image, null );
			} else {
				imagegif( $image, $file_name );
			}
			break;
		case 'jpg':
		case 'jpeg':
			$quality = is_null( $quality ) ? 85 : $quality;
			if ( is_null( $file_name ) ) {
				header( 'Content-Disposition: inline;filename=' . $font_file_name . '.' . $file_type );
				header( 'Content-Type: image/jpeg' );
				imagejpeg( $image, null, $quality );
			} else {
				imagejpeg( $image, $file_name, $quality );
			}
			break;
		case 'png':
		default:
			$quality = is_null( $quality ) ? 9 : $quality;
			if ( is_null( $file_name ) ) {
				header( 'Content-Disposition: inline;filename=' . $font_file_name . '.png' );
				header( 'Content-Type: image/png' );
				imagepng( $image, null, $quality, PNG_NO_FILTER );
			} else {
				imagepng( $image, $file_name, $quality, PNG_NO_FILTER );
			}
			break;
	}
	imagedestroy( $image );

	return true;
}

Nếu tham số $output là null thì tập tin PHP sẽ xuất ra theo kiểu hình ảnh, bạn có thể truyền tham số thông qua url của file PHP, sau đó cho đường dẫn file này vào thuộc tính src của thẻ img để hiển thị.

Leave a Reply

Be the First to Comment!

Notify of
avatar
wpDiscuz