PHP Conference Japan 2024

imagecreatefromstring

(PHP 4 >= 4.0.4, PHP 5, PHP 7, PHP 8)

imagecreatefromstring从字符串中的图像流创建新图像

描述

imagecreatefromstring(string $data): GdImage|false

imagecreatefromstring() 返回一个图像标识符,表示从给定 data 获得的图像。如果您的 PHP 版本支持这些类型,则将自动检测:JPEG、PNG、GIF、BMP、WBMP、GD2、WEBP 和 AVIF。

参数

data

包含图像数据的字符串。

返回值

成功时将返回一个图像对象。如果图像类型不受支持、数据格式不被识别或图像已损坏且无法加载,则返回 false

错误/异常

imagecreatefromstring() 如果数据格式不被识别,则会引发 E_WARNING 级别的错误。

变更日志

版本 描述
8.0.0 成功时,此函数现在返回一个 GDImage 实例;以前,返回一个 resource
7.3.0 现在支持 WEBP(如果使用的 libgd 支持)。

示例

示例 #1 imagecreatefromstring() 示例

<?php
$data
= 'iVBORw0KGgoAAAANSUhEUgAAABwAAAASCAMAAAB/2U7WAAAABl'
. 'BMVEUAAAD///+l2Z/dAAAASUlEQVR4XqWQUQoAIAxC2/0vXZDr'
. 'EX4IJTRkb7lobNUStXsB0jIXIAMSsQnWlsV+wULF4Avk9fLq2r'
. '8a5HSE35Q3eO2XP1A1wQkZSgETvDtKdQAAAABJRU5ErkJggg==';
$data = base64_decode($data);

$im = imagecreatefromstring($data);
if (
$im !== false) {
header('Content-Type: image/png');
imagepng($im);
imagedestroy($im);
}
else {
echo
'发生错误。';
}
?>

以上示例将输出类似以下内容

Output of example : imagecreatefromstring()

参见

添加注释

用户贡献的注释 16 条注释

32
ville dot jungman at gmail dot com
16 年前
从互联网下载图像时,最简单的方法是让 php 决定文件类型。因此,忘记使用 imagecreatefromjpg、imagecreatefromgif 和 imagecreatefrompng。相反,这是要走的路

<?php
$src
= "http://www.varuste.net/tiedostot/l_ylabanneri.jpg";
$image = imagecreatefromstring(file_get_contents($src));
?>
5
anon at dude dot com
8 年前
(编者注:从 PHP 7.2.0 开始将支持 BMP。)

如果从 GD 中缺少“imagecreatefrombmp()”这一点不明显,那么此函数也不能处理普通的 BMP 文件。
9
php dot net at phor dot net
15 年前
我的网站允许匿名上传到网络可访问的位置(如果找到脚本,该位置将执行脚本)。

当然,我需要验证只接受无害的内容。我期望只有图像,所以我使用

<?php
$im
= $imagecreatefromstring($USERFILE);
$valid = ($im != FALSE);
imagedestroy($im);
return
$valid;
?>
4
chris at haydenwheeler dot com
5 年前
imagecreatefromstring 似乎不支持 WebP 图像(在 PHP 7.2.10 上测试,启用了 GD 2.1.0 和 GD WebP 支持)。
5
logan at logansbailey dot com
15 年前
所以你们不要花一个小时来弄清楚为什么当你们使用这个或其他 imagecreatefrom 函数时,你们的脚本总是内存不足。当您使用这些函数时,GD 会解压缩图像,这可能导致您的脚本内存不足。

如果您下载一个原始图像并将其保存在您的计算机上为 jpeg,以便文件大小减小,GD 将自动将其转换为原始图像,并且您可能会内存不足。
1
junkmail at pmobl dot com
18 年前
我知道很多人在使用 Sprint PPC6700 上的图像与 GD 时遇到了麻烦。jpeg 库总是会抛出一个关于 16 个字节的额外数据的错误。我决定在十六进制编辑器中四处探查,发现这些额外字节出现在 exif 数据的末尾。

通过删除这些额外数据,图像可以很容易地由 GD 和 EXIF 扩展作为普通图像进行操作。这也消除了使用 GIMP 的图像出现任何问题,因为 GIMP 必须依赖于相同的 jpeg 库。

这是一个函数,它将检查图像是否来自 PPC6700,然后为您删除额外的数据。结果可以成功地与 imagecreatefromstring 一起使用

作者:Paul Visco
IM:paulsidekick
创建日期:2-12-06

function checkFixPPC6700($orig){

//获取文件内容
$data = file_get_contents($orig);

//如果它是 PPC 6700 图像,则剪切掉额外的 16 位
if(strstr($data, "\x41\x70\x61\x63\x68\x65\x00\x48")){
//下一行可以全部是一个字符串,我将其拆分,以便 php.net 上的表单可以接受它
$bad_data ="\x00\x10\x4A\x46" . "\x49\x46\x00\x01\x01" . "\x00\x00\x01\x00\x01\x00\x00";
return substr_replace($data, "", strpos($data, $bad_data),
strlen($bad_data));
} else {
//如果不是来自 PPC 6700,则返回未更改的数据
return $data;
}

}
1
Blizzke at gmail dot com
17 年前
我使用动态生成的图像,这些图像在显示之前需要稍微修饰一下。因此,从本质上讲,我做了一些基本工作,然后将图像存储在内存缓存(APC)中,稍后从缓存中再次将图像“加载到”GD 中,进行最终处理,然后显示图像。
由于我想避免大量磁盘访问,所以我使用了输出缓冲函数

<?php
//执行图像处理操作

//开始缓冲
ob_start ( );
ImageGD ( $hImage );
$sImage = ob_get_contents ( );
ob_end_clean ( );

//将内容放入缓存

//从缓存重新加载并重新创建图像
$hImage = imagecreatefromstring ( $sImage );

//执行最终编辑操作并输出图像
?>

当然,这是一个简化的示例,我只是想分享这个想法。
2
hope at it-helps dot com
13 年前
从文件创建图像资源,无需知道图像类型

<?php
function imagecreatefromfile($imagepath=false) {
if(!
$imagepath || !$is_readable($imagepath) return false;
return @
imagecreatefromstring(file_get_contents($imagepath));
}
$img_resource=imagecreatefromfile($imagepath);
?>
-2
adeline dot duterre at boxify dot be
4 年前
许多网站在将 .jpg / .png 转换为 base64 的过程中,会在 base64 字符串之前添加一些文字:"data:image/png;base64,"

如果你保留这些文字,PHP 函数将返回错误 "Data is not in a recognized format in"。

如果你遇到这种情况

$image_string=str_replace("data:image/png;base64,","",$image_string);
$image_string = base64_decode($image_string);
$img = imagecreatefromstring($image_string);
-1
alexandrebr at ignorethis dot gmail dot com
19 年前
一个简单的例子,帮助理解这个函数...

<?
$loadFile = "http://static.php.net/images/php.gif";

$im = imagecreatefromstring(file_get_contents($loadFile));
// 等同于 imagecreatefromgif($loadFile);
imagegif($im);
?>

该函数将尝试自动确定文件格式(jpg、gif、png……),如果失败则返回 false。
-3
paul at epeeps dot net
19 年前
我运行着一个博客网站,允许用户从他们的手机发布图片。由于某种原因,诺基亚 3220 生成的 jpeg 文件在 EOF 0xFFF9 之前包含额外的數據。

我编写了这个类,允许你修复这些图片,以便可以使用 GD 库进行调整大小和处理。如果不应用修复,GD 和 gimp 都会报告文件错误。它基本上会不断读取垃圾部分的字节,直到文件成为有效的 jpeg。这里有一个诺基亚 3220 生成的有问题的图片示例,你可以用它来测试 http://www.shawnrider.com/moblog/cache/0854747001121624103.jpg

/*
作者:Paul Visco
主页:http://www.elmwoodstrip.com?u=paul
AIM:paulsidekick
说明:该文件允许你修复诺基亚 3220 拍照手机创建的 jpeg 文件,以便可以使用 PHP 的 GD 库对其进行处理。

用法:只需实例化该类,然后为每个图像调用 fix 方法。
例如:
$nokia = new nokia;
$nokia->debug ="y";
$nokia->fix("yourpic.jpg");
*/

类 nokia
{
public $file;
public $debug = "n";
public $dir_name = "";
private $img; //从字符串创建的图像
private $str;

function fix($file)
{

//设置要修复的文件
$this->file = $file;

//将文件加载到字符串中
$this->str = file_get_contents($this->file);

//测试是否为诺基亚图片或是否之前已损坏
if (substr_count($this->str, chr(0x28).chr(0x36).chr(0x28).chr(0x2B)) == 0 || @imagecreatefromstring($this->str))
{
if ($this->debug =="y")
{
echo "\n<br />".$this->file." 不是损坏的诺基亚图片";
}

return true;
}

//如果不存在且已指定,则为修复的图像创建目录
if(!empty($this->dir_name) && !is_dir($this->dir_name))
{
@mkdir($this->dir_name, 0777);
}

//去除文件中的垃圾数据
$this->eat($this->str);

//将文件写回自身
file_put_contents($this->dir_name.$this->file, $this->str);

//返回 true 表示已修复
return true;

}

function eat()
{

//检查图像
$this->img = @imagecreatefromstring($this->str);

//如果图像无法正常工作,则继续去除垃圾数据
while(!$this->img)
{
//逐个去除错误字节
$this->str= substr_replace($this->str, "", -3, -2);

//再次检查图像
$this->img = @imagecreatefromstring($this->str);
}

if ($this->debug =="y")
{
//通知用户已修复
echo "\n<br />已去除垃圾数据!! ".$this->file." 现在已修复,感谢 p:labs!";
}
return true;
}

}
-3
not given
21 年前
关于上一个问题的一点说明(如果你仍然不知道的话):)…

GIF 是 256 色(或 8 位),而 resample 函数需要真彩色,我猜……这就是为什么它适用于 JPG 而非 GIF。

接下来…你获取一个字符串,将其写入文件,打开文件(imagecreatefromgif),然后再次删除文件。

如果你使用 imagecreatefromstring($string),则可以跳过临时文件部分。
-4
nfo[NOSPAM] at safernetworks dot net
16 年前
我设法解决从文件数据(本地站点或外部站点协议)加载图像文件的唯一方法如下。我希望这能为其他人节省两小时的调试和查找良好示例的时间。
[PHP]

<?php
$sFile
= "http://www.justgreatwine.co.uk/img/vineyard.jpg";
$imagedata = GetFileData($sFile); //以 4k 块加载文件
/*=======输出=========*/
ob_start();
// 假设你在 $imagedata 中有图像数据
$length = strlen($imagedata);
header('Last-Modified: '.date('r'));
header('Accept-Ranges: bytes');
header('Content-Length: '.$length);
header('Content-Type: image/jpeg');
print(
$imagedata);
ob_end_flush();
/*======使用的函数======*/
function GetFileData($sFilePath){
$fp = fopen($sFilePath, 'rb') or die('404! 无法打开文件!');
$buf = '';
while(!
feof($fp)){
$buf .= fgets($fp, 4096);
}
fclose($fp);
return
$buf; //如果失败则返回 False,否则返回最多 FileSize 字节的内容。
}
?>

[/PHP]
-5
shiehj at yahoo dot com
21 年前
这是我创建数据库 blob 字段缩略图的代码。诀窍是使用 "imagecreatefromstring()" 来创建图像文件。

Jack Shieh

<?php
require("dbconfig.inc");

$id = $_GET['id'];

if(
$id) {

$link = @mysql_connect($host, $user, $password) or die("无法连接: " . mysql_error());
@
mysql_select_db($dbname, $link);

$query = "select filetype, image from pictures where id = $id";
$result = @mysql_query($query);

$data = @mysql_result($result,0,"image");
$type = @mysql_result($result,0,"filetype");

Header( "Content-type: $type");

$size = 150; // 新图片宽度
$src = imagecreatefromstring($data);
$width = imagesx($src);
$height = imagesy($src);
$aspect_ratio = $height/$width;

if (
$width <= $size) {
$new_w = $width;
$new_h = $height;
} else {
$new_w = $size;
$new_h = abs($new_w * $aspect_ratio);
}

$img = imagecreatetruecolor($new_w,$new_h);
imagecopyresized($img,$src,0,0,0,0,$new_w,$new_h,$width,$height);

// 确定图片类型并发送给客户端
if ($type == "image/pjpeg") {
imagejpeg($img);
} else if (
$type == "image/x-png") {
imagepng($img);
} else if (
$type == "image/gif") {
imagegif($img);
}
imagedestroy($img);
mysql_close($link);
};
?>
-4
kanzure at gmail dot com
18 年前
在外部程序(在本例中为 gnuplot)中生成图表可能会导致问题。这是一个在深夜拼凑出来的解决方案。

<?php
// 从例如数据库中获取值
$vals = "1 2\\\\n4 8\\\\n"; # 等等
// 构造 gnuplot_call 变量,类似于:
$gnuplot_call = "echo \"set term png; plot '<echo -e \\\"$vals\\\" ' ti 'Updated with' with line ; \" | gnuplot";
ob_start();
passthru($gnuplot_call, $gnuplot_call_output);
$image = imagecreatefromstring(ob_get_contents());
ob_end_clean();
imagepng($image); # 显示
?>
-5
adrian_schmidt at yahoo dot com
21 年前
我正在尝试让 imagecreatefromstring 与 GIF 一起使用。当然,它不会工作。
我已经阅读了提示,但也不能使它们工作。
以下是根据上述提示我尝试的内容

---

header('Content-Type: image/gif');
header('Content-Disposition: inline; filename=file.gif');

$temp = tmpfile();
fwrite($temp, $line['image']);
$src_img = imagecreatefromgif($temp);
fclose($temp); // 这将删除文件
$dst_img = imagecreatetruecolor(100, 100);
imagecopyresampled($dst_img, $src_img, 0,0,0,0, 100,100, imagesx($src_img), imagesy($src_img));

imagegif($dst_img);

---

其中 $line['image'] 是从我的 MySQL 数据库中获取的 gif...

如果任何能够使类似功能工作的人可以给我一段可行的代码,我将不胜感激!

如果可以排除临时文件,那就太好了...

以下是 JPEG 的可行代码

---

header('Content-Type: image/jpeg');
header('Content-Disposition: inline; filename=file.jpg');

$src_img = imagecreatefromstring($line['image']);
$dst_img = imagecreatetruecolor(100, 100);
imagecopyresampled($dst_img, $src_img, 0,0,0,0, 100,100, imagesx($src_img), imagesy($src_img));

imagejpeg($dst_img);
To Top