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ị.

Không có bình luận

Bạn có thể trở thành người đầu tiên để lại bình luận.

Trả lời

Thư điện tử của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *