如果给定字符串 $filename 并且它存在,它将被覆盖。
(PHP 4, PHP 5, PHP 7, PHP 8)
imagejpeg — 将图像输出到浏览器或文件
imagejpeg() 从给定的 image
创建一个 JPEG 文件。
image
一个 GdImage 对象,由图像创建函数(如 imagecreatetruecolor())返回。
file
要保存文件的路径或打开的流资源(在该函数返回后自动关闭)。如果未设置或为 null
,则原始图像流将直接输出。
quality
quality
是可选的,范围从 0(最差质量,文件更小)到 100(最佳质量,文件更大)。默认值 (-1
) 使用默认的 IJG 质量值(约 75)。
示例 #1 将 JPEG 图像输出到浏览器
<?php
// 创建一个空白图像并添加一些文本
$im = imagecreatetruecolor(120, 20);
$text_color = imagecolorallocate($im, 233, 14, 91);
imagestring($im, 1, 5, 5, 'A Simple Text String', $text_color);
// 设置内容类型标头 - 在这种情况下为 image/jpeg
header('Content-Type: image/jpeg');
// 输出图像
imagejpeg($im);
// 释放内存
imagedestroy($im);
?>
上面的示例将输出类似于以下内容
示例 #2 将 JPEG 图像保存到文件
<?php
// 创建一个空白图像并添加一些文本
$im = imagecreatetruecolor(120, 20);
$text_color = imagecolorallocate($im, 233, 14, 91);
imagestring($im, 1, 5, 5, 'A Simple Text String', $text_color);
// 将图像保存为 'simpletext.jpg'
imagejpeg($im, 'simpletext.jpg');
// 释放内存
imagedestroy($im);
?>
示例 #3 将图像以 75% 的质量输出到浏览器
<?php
// 创建一个空白图像并添加一些文本
$im = imagecreatetruecolor(120, 20);
$text_color = imagecolorallocate($im, 233, 14, 91);
imagestring($im, 1, 5, 5, 'A Simple Text String', $text_color);
// 设置内容类型标头 - 在这种情况下为 image/jpeg
header('Content-Type: image/jpeg');
// 使用 NULL 跳过文件参数,然后将质量设置为 75%
imagejpeg($im, NULL, 75);
// 释放内存
imagedestroy($im);
?>
注意:
如果要输出渐进式 JPEG,需要使用 imageinterlace() 启用交错。
我在网上没有找到类似的示例,所以我将一些片段拼凑在一起。希望这能为其他人节省时间!
这是一个从文件系统中读取任何图像(gif jpg png)、将其缩放到最大宽度/高度、保存缩略图到 BLOB 字段并保持原始图像类型的完整解决方案。非常棘手。
<?php
function scaleImageFileToBlob($file) {
$source_pic = $file;
$max_width = 200;
$max_height = 200;
list($width, $height, $image_type) = getimagesize($file);
switch ($image_type)
{
case 1: $src = imagecreatefromgif($file); break;
case 2: $src = imagecreatefromjpeg($file); break;
case 3: $src = imagecreatefrompng($file); break;
default: return ''; break;
}
$x_ratio = $max_width / $width;
$y_ratio = $max_height / $height;
if( ($width <= $max_width) && ($height <= $max_height) ){
$tn_width = $width;
$tn_height = $height;
}elseif (($x_ratio * $height) < $max_height){
$tn_height = ceil($x_ratio * $height);
$tn_width = $max_width;
}else{
$tn_width = ceil($y_ratio * $width);
$tn_height = $max_height;
}
$tmp = imagecreatetruecolor($tn_width,$tn_height);
/* 检查图像是否为PNG或GIF,然后设置是否透明 */
if(($image_type == 1) OR ($image_type==3))
{
imagealphablending($tmp, false);
imagesavealpha($tmp,true);
$transparent = imagecolorallocatealpha($tmp, 255, 255, 255, 127);
imagefilledrectangle($tmp, 0, 0, $tn_width, $tn_height, $transparent);
}
imagecopyresampled($tmp,$src,0,0,0,0,$tn_width, $tn_height,$width,$height);
/*
* imageXXX() 只有两种选择,保存为文件或发送到浏览器。
* 它不提供操作最终 GIF/JPG/PNG 文件流的机会
* 所以我启动输出缓冲区,使用 imageXXX() 将数据流输出到浏览器,
* 获取流的内容,并使用 clean 静默丢弃缓冲的内容。
*/
ob_start();
switch ($image_type)
{
case 1: imagegif($tmp); break;
case 2: imagejpeg($tmp, NULL, 100); break; // 最佳质量
case 3: imagepng($tmp, NULL, 0); break; // 无压缩
default: echo ''; break;
}
$final_image = ob_get_contents();
ob_end_clean();
return $final_image;
}
?>
假设你有一个用户可以上传图片的表单,你需要将图片缩放并保存到数据库中。
<?php
[..] // 用户点击了提交按钮..
// 检查用户是否输入了图片
if ($_FILES['imagefile']['name'] != '') {
$image = scaleImageFileToBlob($_FILES['imagefile']['tmp_name']);
if ($image == '') {
echo '不支持的图片类型';
} else {
$image_type = $_FILES['imagefile']['type'];
$image = addslashes($image);
$query = "UPDATE yourtable SET image_type='$image_type', image='$image' WHERE ...";
$result = mysql_query($query);
if ($result) {
echo '图片已缩放并上传';
} else {
echo '执行查询时出错';
}
}
}
?>
[[编辑注:删除 header()-call,因为它在输出内联图像数据时是不需要的]]
一行代码,解决了我 3 个小时的盲目搜索!
这里:
... ob_start();
imagejpeg( $img, NULL, 100 );
imagedestroy( $img );
$i = ob_get_clean();
echo "<img src='data:image/jpeg;base64," . base64_encode( $i )."'>"; // 救星代码!
如果你使用官方 Docker 镜像并使用 `docker-php-ext-install gd` 启用 gd,默认情况下你不会获得 JPEG 支持。
如果你遇到这种情况,并且得到 "Call to undefined function imagejpeg()" 错误,你需要在 docker-php-ext-install 之前执行以下操作:
docker-php-ext-configure gd --with-jpeg
你还需要安装 libjpeg-dev 才能使它正常工作。
关于 Carl Gieringer 的评论,PHP 文件可以是 utf-8 编码。只要确保编辑器不会输出 BOM,因为 BOM 在 utf-8 中是不必要的。
除了微软的任何编辑器之外,大多数支持 utf 的程序员编辑器都允许你禁止 BOM。
我写了一个脚本,它允许将字母数字数据放在图像上。HTML 功能是 img src,PHP 功能是 imagettftext。这个简单的代码会在图像上从 1 到 3 递增。
代码
<?php
// ImageCall.php -- 此脚本将调用一个脚本来生成图像。
for($next = 1;$next < 4; $next++){
print "Image $next:<br>";
print "<img src = 'Image.php?\$text=$next'>";
print "<br><br>";
}
?>
<?php
//Image.php -- 此脚本创建方形图像并在其上放置文本。
// 图像大小和颜色
$im = ImageCreate(77,77);
$color1 = ImageColorAllocate($im,0x66,0xCC,0x00);
$color2 = ImageColorAllocate($im,0x33,0x66,0x00);
$color3 = ImageColorAllocate($im,0x00,0x99,0x00);
$color4 = ImageColorAllocate($im,0x3D,0x3D,0x3D);
// 图像创建
ImageFilledRectangle($im,1,1,76,76,$color1);
ImageFilledpolygon($im, array (76,1,1,76,76,76),3,$color2);
ImageFilledRectangle($im,5,5,72,72,$color3);
// 确定图像的数字中心
$size = ImageTTFBBox(45,0,'impact',$_GET['$text']);
$X = (77 - (abs($size[2]- $size[0])))/2;
$Y = ((77 - (abs($size[5] - $size[3])))/2 + (abs($size[5] - $size[3])));
// 将数字信息放置在图像上
ImageTTFText($im,45,0,($X-1),$Y,$color4,'impact',$_GET['$text']);
// 将完成的图像返回给调用脚本
Header('Content-Type: image/png');
Imagejpeg($im);
?>
零字节文件结果 - 这是原因!
请牢记此函数上的注意事项。如果 gdlib 无法输出,它仍然会返回 true!我个人认为这是一个错误。
如果您的图像超过其最大未公开尺寸 65500 像素,GD 将无法输出。
您将获得一个零字节文件。
如果您希望将 jpg 数据捕获到一个变量中,而不是将其输出或保存到文件中(也许这样您就可以将其放入数据库中),您可能需要考虑使用输出缓冲。以下类似代码应该可以工作。
<?php
ob_start(); // 启动一个新的输出缓冲区
imagejpeg( $newimage, NULL, 100 );
$ImageData = ob_get_contents();
ob_end_clean; // 停止此输出缓冲区
?>
对于那些收到 "permission denied" 或 "unable to access" 消息的用户:这看起来像是您的文件夹写入权限问题。无论您使用的是 Windows 还是 Linux 服务器,请确保正确用户拥有写入正确文件夹的权限。
关于 chris.calo 的代码
// 以下代码块检索源文件。它假设文件名扩展名与文件的格式匹配。
if ( strpos($source_file,".gif") ) { $img_source = imagecreatefromgif($source_file); }
if ( (strpos($source_file,".jpg")) || (strpos($source_file,".jpeg")) )
... 等等。
它假设的不仅仅是这些,即文件名在字符串中*任何位置*都不包含字符串 ".gif"、".jpg"、".jpeg"、".bmp" 或 ".png"。一些具有特殊文件名的有效文件可能会破坏这一点;例如,一个名为 "used.to.be.a.png.file.gif" 的文件会导致该脚本尝试将该文件加载为 PNG。显然,这是一种罕见的情况,但可以通过使用 "else ifs"(使用更少的 CPU 时间)或检查扩展名是否紧邻字符串的末尾或两者来轻松避免该问题。
也就是说,如果 PHP 没有用不同的函数来处理同一个事情的不同图像格式,整个事情就可以避免了。恶心。
我用 imagejpeg() 函数的图像质量参数做了一个实验,用于创建 jpeg。我发现考虑到文件大小的最佳图像质量为 80 - 非常接近默认值 75。
超过 80 将导致文件大小不必要地增加,而图像质量没有明显提高。
结果和示例图片:http://www.ebrueggeman.com/article_php_image_optimization.php
当我尝试上传和调整大小一个图像时,在 safe_mode 启用的情况下,我遇到了权限被拒绝的问题。这导致我无法在我想用 imagejpeg() 或用 touch() 和 imagejpeg() 重新采样图像的新文件中创建该文件。
以下是我的解决方案,我没有测试过,但这是可能的,它会占用一些内存。
<?php
function resize($image, $target_file) {
// $image 是上传的图像
list($width, $height) = getimagesize($image['tmp_name']);
// 设置图像的新尺寸
$ratio = $width/$height;
$new_height = 500;
$new_width = $new_height * $ratio;
// 将文件移动到新位置
move_uploaded_file($image['tmp_name'], $target_file);
// 对图像进行重新采样
$new_image = imagecreatetruecolor($new_width, $new_height);
$old_image = imagecreatefromjpeg($target_file);
imagecopyresampled($new_image,$old_image,0,0,0,0,$new_width, $new_height, $width, $height);
// 输出
imagejpeg($new_image, $target_file, 100);
}
?>
如您所见,该函数将上传的文件移动到您要保存重新采样图像的位置(move_uploaded_file 不受 safe_mode 限制),然后您可以重新采样图像,因为它已经通过移动它而创建了。
注意:您要保存文件的目录的权限必须设置为 0777。
我来到这里是为了寻找类似于 getJPEGresolution 函数的东西,但注意到在上一篇文章中指出的缺点。因此,在借鉴了网上其他一些代码示例后,我整理了以下函数,它应该始终正确返回正确的值。(但请记住,您仍然需要在您的 PHP 实例中安装 EXIF 扩展才能使此功能正常工作!)
<?php
function jpeg_dpi($filename)
{
if ( exif_imagetype($filename) != IMAGETYPE_JPEG ) {
return false;
} else {
$exif = exif_read_data($filename, 'IFD0');
}
$x = $y = 0;
if ( isset($exif['XResolution']) && isset($exif['YResolution']) ) {
$x = intval(preg_replace('@^(\\d+)/(\\d+)$@e', '$1/$2', $exif['XResolution']));
$y = intval(preg_replace('@^(\\d+)/(\\d+)$@e', '$1/$2', $exif['YResolution']));
}
if ( !$x && !$y && $fp = fopen($filename, 'r') ) {
$string = fread($fp, 20);
fclose($fp);
$data = bin2hex(substr($string, 14, 4));
$x = hexdec(substr($data, 0, 4));
$y = hexdec(substr($data, 4, 4));
}
if ( $x || $y ) {
return array($x, $y);
}
return false;
}
?>
此函数返回一个数组,包含 X 分辨率、Y 分辨率,如果能确定则返回它们,否则返回 FALSE。
关于下面的代码,它只获取 JFIF 模式下 DPI 信息的最后一个字节。我想知道为什么我的 300 DPI 文件被报告为 44。当然,300 - 256 = 44。
对于那些想在不使用 GD 或 ImageMagic 的情况下获取 JPEG 图片分辨率的人来说……我编写了这个简单的函数。
可惜 GD 没有提供这个非常简单的函数供我们使用……
<?php
function getJPEGresolution($filename){
$outRez=array();
// 读取文件
ob_start(); // 开始一个新的输出缓冲区
$image = file_get_contents($filename);
// 从 JPG 头部获取 DPI 信息
$outRez["xDPI"] = ord($image[15]);
$outRez["yDPI"] = ord($image[17]);
ob_end_clean(); // 停止此输出缓冲区
// xDPI 和 yDPI 的值应该相等……但我们无论如何都会输出两者……
return($outRez);
}//end function getJPEGresolution
?>
这里有一个函数可以调整图片大小并保持纵横比。它会调整 JPEG、GIF 或 PNG 的大小,可以轻松地修改以添加 BMP。name 字段是文件名的目标,不包括文件扩展名。
<?php
// name= 文件名减去类型
function createImage($uploadedfile,$newWidth,$name)
{
// 获取上传图片的原始大小
if(!$info=getimagesize($uploadedfile))
return false;
switch ($info['mime'])
{
case 'image/jpeg':
$src = imagecreatefromjpeg($uploadedfile);
break;
case 'image/gif':
$src = imagecreatefromgif($uploadedfile);
break;
case 'image/png':
$src = imagecreatefrompng($uploadedfile);
break;
default:
return false;
}
// 更改文件名以添加文件类型
$mime=split("image/",$info['mime']);
$filename=$name.".".$mime[1];
$size = getimagesize($uploadedfile);
$newHeight=aspect_ratio($size[0],$newWidth,$size[1]);
$tmp=imagecreatetruecolor($newWidth,$newHeight);
// 这行代码实际上执行图片大小调整,将原始图片复制到 $tmp 图片中
// image
imagecopyresampled($tmp,$src,0,0,0,0,$newWidth,$newHeight,$info[0], $info[1]);
switch ($info['mime'])
{
case 'image/jpeg':
imagejpeg($tmp,$filename,100); // 100 是质量设置,值范围为 0-100。
break;
case 'image/gif':
imagegif($tmp,$filename,100); // 100 是质量设置,值范围为 0-100。
break;
case 'image/png':
imagepng($tmp,$filename); // 100 是质量设置,值范围为 0-100。
break;
}
imagedestroy($src);
imagedestroy($tmp); // 注意:PHP 会在请求完成后清理它创建的临时文件。
//
return true;
}
if(!createImage($uploadedfile,100, "uploaded_images/imgname"))
{
echo "error";
}
?>
这是另一个即时创建缩略图的脚本。
当我在我的页面上编写图片查看器脚本时,所有图片都只有全尺寸和高质量,因为我想让访客能够下载图片。
但由于超过 4 MP 的图片大小对于网站来说太大了,我创建了缩略图和更小的图片,这些图片是即时生成的。但我发现,脚本需要太多内存,尤其是在缩略图概述中,当我同时创建 50 多个缩略图时。
因此,我修改了我的图片创建器和查看器,让他们存储生成的图片。这样,只有第一个访问者需要等待(通常是我来控制上传和更新),其他访问者都可以获取存储的图片,速度要快得多。
创建不同的文件夹。我有一个名为“imagesdb”的主文件夹,以及三个子文件夹:full(全尺寸图片)、show(图片查看器中的图片)和 thumb(概述中的缩略图)。
将脚本存储为 image.php,并像这样链接它
<?PHP
$image_name = "foo.jpg";
$style = "show";
// 我已经获得了文件夹名称。比较简单。对于
// 缩略图,将 "show" 替换为 "thumb"。
$image_name = "imagesdb/$style/$image_name";
if(!file_exists($image_name))
$image_name = "image.php?image_name=$image_name&style=$style";
// 只有在文件不存在的情况下,才会调用动态创建文件
?>
现在是主脚本,存储在文件 image.php 中
<?PHP
$image_name = $_GET['image_name'];
$style = $_GET['style'];
// 现在将最大尺寸设置到不同的样式。
// 你可以设置额外的样式,但请记住
// 创建相应的子文件夹。
switch($style) {
case "show":
$max_size = 800;
break;
case "thumb":
$max_size = 125;
}
$dest_file = "imagesdb/$style/$image_name";
// 设置输出文件
$image_file = "imagesdb/full/$image_name";
// 设置源文件
$size = getimagesize($image_file);
// 获取原始尺寸
if($size[0] > $size[1]) {
$divisor = $size[0] / $max_size;
}
else {
$divisor = $size[1] / $max_size;
}
// 为了始终获得相同尺寸的图片,这在图片查看器中通常是需要的,看看哪个更大:
// 宽度或高度
$new_width = $size[0] / $divisor;
$new_height = $size[1] / $divisor;
// 设置新的尺寸
settype($new_width, 'integer');
settype($new_height, 'integer');
// 尺寸应该是整数
$image_big = imagecreatefromjpeg($image_file);
// 加载原始图片
$image_small = imagecreatetruecolor($new_width, $new_height);
// 创建新图片
imagecopyresampled($image_small, $image_big, 0,0, 0,0, $new_width,$new_height, $size[0],$size[1]);
// imageresampled 会产生比 imageresized 质量更高的效果
// imageresized
imagedestroy($image_big);
// 原始数据不再使用
header("Content-type: image/jpeg");
if($style=="show" || $style=="thumb") {
if(!file_exists($dest_file))
imagejpeg($image_small, $dest_file, 100);
}
// 如果你设置了额外的尺寸,也请将它们放到
// if-参数中。
// 如果有人直接在
// 浏览器中调用 image.php 并且图片名称已经存在,它们
// 不会被覆盖
imagejpeg($image_small, '', 100);
imagedestroy($image_small);
// 最后将图片发送到浏览器,并销毁不再
// 需要的图片数据。
?>
由于这个网站在过去多次帮助过我,并在创建这个脚本方面提供了帮助,我希望能够用这个脚本帮助其他人,为他们节省开发更高效的解决方案的时间,而这种解决方案比始终动态创建脚本更有效。
感谢 Chris dot Calo 提供的缩略图代码片段。文件类型问题很容易通过使用 getimagesize 从文件中获取类型来解决,你也可以在这个阶段处理不支持的类型。因此
list($img_width,$img_height, $type) = getimagesize($source_file); // 获取原始尺寸
if ($type != 1 && $type != 2 && $type != 3 && $type != 15) { die("Your file is not a supported format"); }
...然后稍后再次检查类型以正确打开图片
if ( $type == 1 ) { $img_source = imagecreatefromgif($source_file); }
else if ( $type == 2 ) { $img_source = imagecreatefromjpeg($source_file); }
else if ( $type == 3 ) { $img_source = imagecreatefrompng($source_file); }
else if ( $type == 15 ) { $img_source = imagecreatefromwbmp($source_file); }
你好
我遇到了类似的安全模式问题。我的解决方案是
在 imagejpeg()、touch() 等之前
写入
ini_set(safe_mode,Off);
以及在所有操作之后
ini_set(safe_mode,On);
很奇怪,但它确实有效
祝大家一切顺利
请注意,对于当前在此功能上失效的安全模式行为,有一个 bug 报告
http://bugs.php.net/?id=35060
根据回应的 PHP 员工的说法,文档是错误的(我不同意,但我也不是他们的员工)。
解决方法是在使用 imagejpeg() 之前,首先使用 touch()(或任何其他可以执行此操作的文件系统功能)创建文件。
>>Bram Van Dam 的
下面的注释中缺少 "()",在 ob_end_clean 调用中
ob_end_clean; // 停止此输出缓冲区
应该改为
ob_end_clean(); // 停止此输出缓冲区
然后,你可以使用它来添加 content-length 标头(例如,Flash 需要事先提供 content-length 才能创建加载器)
例如
...
ob_start(); // 启动新的输出缓冲区
imagejpeg( $newimage, "", 90 );
$ImageData = ob_get_contents();
$ImageDataLength = ob_get_length();
ob_end_clean(); // 停止此输出缓冲区
header("Content-type: image/jpeg") ;
header("Content-Length: ".$ImageDataLength);
echo $ImageData;
...
这是一个简单但功能强大的脚本,用于动态创建缩略图。
你可以包含该脚本
直接到网页中 - 只需将其放在 <img src= 标签中即可。
宽度为 150 像素。
此调整器保留纵横比。
以下是脚本
<?php
// 以这种方式使用它: resize.php?pic=imageurl&width=width_in_pixels
// [email protected] 2004
header("Content-type: image/jpeg");
$im = imagecreatefromjpeg($pic);
$orange = imagecolorallocate($im, 220, 210, 60);
$px = (imagesx($im) - 7.5 * strlen($string)) / 2;
$old_x=imageSX($im);
$old_y=imageSY($im);
$new_w=(int)($width);
if (($new_w<=0) or ($new_w>$old_x)) {
$new_w=$old_x;
}
$new_h=($old_x*($new_w/$old_x));
if ($old_x > $old_y) {
$thumb_w=$new_w;
$thumb_h=$old_y*($new_h/$old_x);
}
if ($old_x < $old_y) {
$thumb_w=$old_x*($new_w/$old_y);
$thumb_h=$new_h;
}
if ($old_x == $old_y) {
$thumb_w=$new_w;
$thumb_h=$new_h;
}
$thumb=ImageCreateTrueColor($thumb_w,$thumb_h);
imagecopyresized($thumb,$im,0,0,0,0,$thumb_w,$thumb_h,$old_x,$old_y);
imagejpeg($thumb,"",90);
imagedestroy($thumb);
?>
在将图像输出到浏览器时需要注意…
确保在您正在编辑的文件以及任何包含文件中,<?php ?> 标签周围没有多余的空格。
我开始以为 GD 或者其他地方有 bug,然后我检查了正在处理的文件,却忘记了 include 文件…
几小时过去了…
与其使用上面描述的临时文件,不如直接缓冲输出流。有人向我展示了这个方法,看起来非常有效。
// 开始缓冲输出流
ob_start();
// 将图像作为文件输出到输出流
Imagejpeg($im);
// 读取输出缓冲区
$buffer = ob_get_contents();
// 清除缓冲区
ob_end_clean();
// 随意使用 $buffer …
看起来在脚本中使用 imageJPEG() 函数时,JPEG 文件中指定的任何分辨率设置都会丢失。
我有一个高分辨率的 JPEG,我在其中使用 imagestringup() 添加了文本,以便我的客户可以将通过电子邮件发送的 JPEG 打印为填写好的表格,但是从 Photoshop 打印出来的图形表明,创建的任何 JPEG 都会被降采样到 72 dpi,而宽度和高度保持不变。
(72 dpi 是标准的网页分辨率)
没什么好奇怪的,但也许如果你读到这篇文章,你就不用挠头了:)
感谢 Stuart 和 Darren 对 create_thumbnail 函数的修正。关于该函数的另一个说明:imagecreatefromwbmp 被错误地使用了。WBMP 是无线位图,而不是 Windows 位图(感谢 clambert at whitecrown),因此该缩略图程序无法处理 Windows 位图。有关处理 Windows 位图的提示,请参见 http://us2.php.net/manual/en/function.imagecreatefromwbmp.php 中的说明。
所以… 在与这个庞大的函数纠缠了几个小时之后,我发现它既没有保留用于创建图像的资源,也没有保留 imagepng() 或 imagegif()。我的意思是,你不能对同一个资源运行两次 imagejpeg()、imagepng() 或 imagegif() 调用。另一个可能未记录的怪癖… :-(
使用 imagepng 或 imagejpeg 显示图像时,您可能需要在 imagepng 和 imagejpeg 函数之前调用 "header("Content-type: image/jpeg")"。
看起来某些服务器/浏览器会剥离默认的标题,因此图像无法呈现并显示为原始数据。
(例如,Firefox 1.02+ 和 OSX Safari)
我在 Kokesh 的脚本中更改了一行
上面列出的 2004 年 6 月 25 日 06:42,现在它生成更高质量的缩略图。
您需要将函数 imagecopyresized() 更改为 imagecopyresampled()
[编辑注:根据 roberto at ilpiola.it 的说明进行修正]
我找不到使用 GD 库更改 JPG 文件的 DPI 信息的任何信息。由于更改它不会调整实际图像的大小或缩放,它只是一个标题设置。
以下代码段将您的 $image 保存到 $file 并将 DPI 设置为 150。
<?php
imagejpeg($image, $file, 75);
// 更改 DPI
$dpi_x = 150;
$dpi_y = 150;
// 读取文件
$size = filesize($file);
$image = file_get_contents($file);
// 更新 JPG 标题中的 DPI 信息
$image[13] = chr(1);
$image[14] = chr(floor($dpi_x/256));
$image[15] = chr( $dpi_x%256);
$image[16] = chr(floor($dpi_y/256));
$image[17] = chr( $dpi_y%256);
// 编写新的 JPG
$f = fopen($file, 'w');
fwrite($f, $msg, $size);
fclose($f);
?>
附注:尚未完全测试,但对我的图像有效…
别忘了 JPEG 压缩会有伪影!而且并非所有的伪影都很明显。PHP 的 JPEG 压缩相当不错,但它似乎通常会
- 使图像整体变亮,程度合理(以前从未见过,但会让图形设计师抓狂,你可能想在压缩之前将图像变暗)
- 降低饱和度,尤其是对于在几个像素内有许多不同颜色的图像(这是 JPEG 的已知特性)
- 严重影响蓝色,这是所有 JPEG 的常见问题,但在某些情况下蓝色和黑色或其他详细的蓝色部分会让人非常讨厌
如果上述问题对您有影响,或者您的图像不是非常像照片,您可能想考虑使用 imagepng() 并输出 PNG 图像而不是 JPEG。有时我会让算法比较 JPEG 和 PNG,然后将较小的版本发送给用户。
此外,使用 imagepng() 时,您应该在 95% 的情况下使用 imageinterlace()。交错的 JPEG 逐步加载,在图像加载时质量会逐渐提高,因此速度较慢的连接的用户可以以低质量看到整个图像。所有这些都在不影响文件大小(实际上,有时文件大小更小!)或最终质量的情况下完成。
希望这能帮到一些人。如果没有大量尝试,这不是很明显。
-Galen
http://zinkconsulting.com/
不要像我一样,绞尽脑汁几个小时,试图弄清楚为什么我的 xxx.php 文件输出 http://localhost/xxx.php 作为单行响应。
为什么?
最有可能的是,你:
1. 在 php 标签之前或之后有空格
2. 需要设置 header('Content-type: image/jpeg');
3. 如果你有需要文件,确保没有输出,不要使用测试打印语句,因为页面需要图片信息
4. 你的代码里有错误
在我的情况下,是第 4 点。函数调用 base64decode 不起作用是有原因的...
实际上是:base64_decode()
顺便说一句,验证以 base64 编码的图片的其他方法是使用以下标签:
echo '<img src="data:image/jpeg;base64,'.$row['IMAGE'].'" alt="photo">';
我从 MySQL 数据库中提取了一个以 base64 编码的 blob 数据,并尝试在页面上渲染它
希望这能帮助到一些人。
将手册中的示例改写成以下函数,用于创建缩略图
function thumbnail_jpeg ($original, $thumbnail, $width, $height, $quality) {
list($width_orig, $height_orig) = getimagesize($original);
if ($width && ($width_orig < $height_orig)) {
$width = ($height / $height_orig) * $width_orig;
}
else {
$height = ($width / $width_orig) * $height_orig;
}
$image_p = imagecreatetruecolor($width, $height);
$image = imagecreatefromjpeg($originial);
imagecopyresampled($image_p, $image, 0, 0, 0, 0, $width, $height, $width_orig, $height_orig);
imagejpeg($image_p, $thumbnail, $quality);
return;
}
这里有一个示例函数,用于创建源 JPEG 文件的缩略图。缩略图将为方形(宽度和高度相同),原始图片将被裁剪以适合缩略图。
参数
$p_thumb_file - 缩略图保存到的文件名(包括路径)
$p_photo_file - 源 JPEG 文件名(包括路径),用于创建缩略图
$p_max_size - 缩略图图片的宽度和高度(将相同),以像素为单位
$p_quality - JPEG 缩略图的质量
<?php
function photoCreateCropThumb ($p_thumb_file, $p_photo_file, $p_max_size, $p_quality = 75) {
$pic = @imagecreatefromjpeg($p_photo_file);
if ($pic) {
$thumb = @imagecreatetruecolor ($p_max_size, $p_max_size) or die ("Can't create Image!");
$width = imagesx($pic);
$height = imagesy($pic);
if ($width < $height) {
$twidth = $p_max_size;
$theight = $twidth * $height / $width;
imagecopyresized($thumb, $pic, 0, 0, 0, ($height/2)-($width/2), $twidth, $theight, $width, $height);
} else {
$theight = $p_max_size;
$twidth = $theight * $width / $height;
imagecopyresized($thumb, $pic, 0, 0, ($width/2)-($height/2), 0, $twidth, $theight, $width, $height);
}
ImageJPEG ($thumb, $p_thumb_file, $p_quality);
}
}
?>
function create_thumbnail( $source_file, $destination_file, $max_dimension)
{
list($img_width,$img_height) = getimagesize($source_file); // 获取原始尺寸
$aspect_ratio = $img_width / $img_height;
if ( ($img_width > $max_dimension) || ($img_height > $max_dimension) ) // 如果任何尺寸过大...
{
if ( $img_width > $img_height ) // 对于宽图片...
{
$new_width = $max_dimension;
$new_height = $new_width / $aspect_ratio;
}
elseif ( $img_width < $img_height ) // 对于高图片...
{
$new_height = $max_dimension;
$new_width = $new_height * $aspect_ratio;
}
elseif ( $img_width == $img_height ) // 对于方形图片...
{
$new_width = $max_dimension;
$new_height = $max_dimension;
}
else { echo "Error reading image size."; return FALSE; }
}
else { $new_width = $img_width; $new_height = $img_height; } // 如果已经更小,则不要改变尺寸。
// 确保这些是整数。
$new_width = intval($new_width);
$new_height = intval($new_height);
$thumbnail = imagecreatetruecolor($new_width,$new_height); // 在内存中创建一个新图片。
// 以下代码块检索源文件。它假设文件名扩展名与文件的格式匹配。
if ( strpos($source_file,".gif") ) { $img_source = imagecreatefromgif($source_file); }
if ( (strpos($source_file,".jpg")) || (strpos($source_file,".jpeg")) )
{ $img_source = imagecreatefromjpeg($source_file); }
if ( strpos($source_file,".bmp") ) { $img_source = imagecreatefromwbmp($source_file); }
if ( strpos($source_file,".png") ) { $img_source = imagecreatefrompng($source_file); }
// 这里我们重新采样并创建新的 JPEG。
imagecopyresampled($thumbnail, $img_source, 0, 0, 0, 0, $new_width, $new_height, $img_width, $img_height);
imagejpeg( $thumbnail, $destination_file, 100 );
// 最后,我们销毁内存中的两个图片。
imagedestroy($img_source);
imagedestroy($thumbnail);
}