php图片保存、下载
<?php
//获取图片2进制内容 ,可以保存入数据库
$imgStr = file_get_contents('http://.../1.jpg'); //保存图片
$fp = fopen('test.jpg','wb');
fwrite($fp, $imgStr); //直接输出图片
header("Content-type: image/gif");
echo $imgStr; //弹出图片下载框
$filename = "1.jpg";//图片地址,可以绝对地址也可以相对地址
header("Content-Type: application/force-download");
header('Content-Disposition: attachment; filename="'.$filename.'"');
$img = file_get_contents($filename);
echo $img;

php获取远程图片并下载保存到本地

/*
*功能:php完美实现下载远程图片保存到本地
*参数:文件url,保存文件目录,保存文件名称,使用的下载方式
*当保存文件名称为空时则使用远程文件原来的名称
*/
function getImage($url,$save_dir='',$filename='',$type=0){
if(trim($url)==''){
return array('file_name'=>'','save_path'=>'','error'=>1);
}
if(trim($save_dir)==''){
$save_dir='./';
}
if(trim($filename)==''){//保存文件名
$ext=strrchr($url,'.');
if($ext!='.gif'&&$ext!='.jpg'){
return array('file_name'=>'','save_path'=>'','error'=>3);
}
$filename=time().$ext;
}
if(0!==strrpos($save_dir,'/')){
$save_dir.='/';
}
//创建保存目录
if(!file_exists($save_dir)&&!mkdir($save_dir,0777,true)){
return array('file_name'=>'','save_path'=>'','error'=>5);
}
//获取远程文件所采用的方法
if($type){
$ch=curl_init();
$timeout=5;
curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch,CURLOPT_CONNECTTIMEOUT,$timeout);
$img=curl_exec($ch);
curl_close($ch);
}else{
ob_start();
readfile($url);
$img=ob_get_contents();
ob_end_clean();
}
//$size=strlen($img);
//文件大小
$fp2=@fopen($save_dir.$filename,'a');
fwrite($fp2,$img);
fclose($fp2);
unset($img,$url);
return array('file_name'=>$filename,'save_path'=>$save_dir.$filename,'error'=>0);
}

分享一个PHP下载远程图片的函数

由于工作中有一个下载远程图片的需求,所以在网上搜索了一下相关方法, 发现网上大多数代码类似如下:

/**
* 抓取远程图片
*
* @param string $url 远程图片路径
* @param string $filename 本地存储文件名
*/
function grabImage($url, $filename = '') {
if($url == '') {
return false; //如果 $url 为空则返回 false;
}
$ext_name = strrchr($url, '.'); //获取图片的扩展名
if($ext_name != '.gif' && $ext_name != '.jpg' && $ext_name != '.bmp' && $ext_name != '.png') {
return false; //格式不在允许的范围
}
if($filename == '') {
$filename = time().$ext_name; //以时间戳另起名
}
//开始捕获
ob_start();
readfile($url);
$img_data = ob_get_contents();
ob_end_clean();
$size = strlen($img_data);
$local_file = fopen($filename , 'a');
fwrite($local_file, $img_data);
fclose($local_file);
return $filename;
}

上面的函数有几个缺点:

1.不能自动识别图片后缀名(很多图片的url并不指向一个静态图片地址,而是直接将图片流输出到客户端)

2.不支持图片url的302跳转

这个函数并不符合本人项目的需求,于是花了点时间自己写了一个下载函数,此函数支持:

1.静态图片下载

2.服务端直接输出图片流下载

3.服务端使用302跳转到真实图片地址的下载(可限定跳转次数)

函数代码如下:

/**
* 下载远程图片
* @param string $url 图片的绝对url
* @param string $filepath 文件的完整路径(包括目录,不包括后缀名,例如/www/images/test) ,此函数会自动根据图片url和http头信息确定图片的后缀名
* @return mixed 下载成功返回一个描述图片信息的数组,下载失败则返回false
*/
function downloadImage($url, $filepath) {
//服务器返回的头信息
$responseHeaders = array();
//原始图片名
$originalfilename = '';
//图片的后缀名
$ext = '';
$ch = curl_init($url);
//设置curl_exec返回的值包含Http头
curl_setopt($ch, CURLOPT_HEADER, 1);
//设置curl_exec返回的值包含Http内容
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
//设置抓取跳转(http 301,302)后的页面
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
//设置最多的HTTP重定向的数量
curl_setopt($ch, CURLOPT_MAXREDIRS, 2); //服务器返回的数据(包括http头信息和内容)
$html = curl_exec($ch);
//获取此次抓取的相关信息
$httpinfo = curl_getinfo($ch);
curl_close($ch);
if ($html !== false) {
//分离response的header和body,由于服务器可能使用了302跳转,所以此处需要将字符串分离为 2+跳转次数 个子串
$httpArr = explode("\r\n\r\n", $html, 2 + $httpinfo['redirect_count']);
//倒数第二段是服务器最后一次response的http头
$header = $httpArr[count($httpArr) - 2];
//倒数第一段是服务器最后一次response的内容
$body = $httpArr[count($httpArr) - 1];
$header.="\r\n"; //获取最后一次response的header信息
preg_match_all('/([a-z0-9-_]+):\s*([^\r\n]+)\r\n/i', $header, $matches);
if (!empty($matches) && count($matches) == 3 && !empty($matches[1]) && !empty($matches[1])) {
for ($i = 0; $i < count($matches[1]); $i++) {
if (array_key_exists($i, $matches[2])) {
$responseHeaders[$matches[1][$i]] = $matches[2][$i];
}
}
}
//获取图片后缀名
if (0 < preg_match('{(?:[^\/\\\\]+)\.(jpg|jpeg|gif|png|bmp)$}i', $url, $matches)) {
$originalfilename = $matches[0];
$ext = $matches[1];
} else {
if (array_key_exists('Content-Type', $responseHeaders)) {
if (0 < preg_match('{image/(\w+)}i', $responseHeaders['Content-Type'], $extmatches)) {
$ext = $extmatches[1];
}
}
}
//保存文件
if (!empty($ext)) {
$filepath .= ".$ext";
//如果目录不存在,则先要创建目录
CFiles::createDirectory(dirname($filepath));
$local_file = fopen($filepath, 'w');
if (false !== $local_file) {
if (false !== fwrite($local_file, $body)) {
fclose($local_file);
$sizeinfo = getimagesize($filepath);
return array('filepath' => realpath($filepath), 'width' => $sizeinfo[0], 'height' => $sizeinfo[1], 'orginalfilename' => $originalfilename, 'filename' => pathinfo($filepath, PATHINFO_BASENAME));
}
}
}
}
return false;
}

经测试,此函数能应付绝大多数类型远程图片下载的处理。

最新文章

  1. C#-WinForm-Treeview-树状模型
  2. [Head First设计模式]一个人的平安夜——单例模式
  3. Python函数信息
  4. LayoutInflater和inflate()
  5. 树形dp--hdu 3534 Tree
  6. AndroidManifest File Features
  7. iOS 学习笔记 十三 (2015.04.15)采用第三方库,实现ios录音转为amr
  8. 【转】React.js 概览
  9. word2013中取消句首字母自动大写
  10. &lt;%@page include%&gt;、&lt;%@include%&gt;、&lt;jsp:include&gt;三者之间的本质区别
  11. ListView item 中TextView 如何获取长按事件
  12. jquery easyui Tab 引入页面的问题
  13. C#的事件处理机制
  14. 类图class的依赖关系
  15. 转:如何让LoadRunner实现多个场景运行?
  16. Linux SVN安装
  17. 解决 Cannot get IBus daemon address 问题
  18. 【转载】安装 gephi 软件
  19. 正则表达式校验yyyymmdd
  20. JS中原始类型Null和Undefined

热门文章

  1. vue created 生命周期
  2. android tooggle button
  3. 浅谈EntityFramework框架的使用
  4. C#中的里氏替换原则
  5. Android基础笔记(十八)- Fragment
  6. How to Use HTML5 FUll Screen API(怎样使用HTML5全屏接口)
  7. YUV Player
  8. [译]GLUT教程 - 位图字体
  9. Unity UGUI——提供可视功能的UI组件(Text)
  10. wamp 两个不同的php.ini