MENU

PHP图片转换为base64编码

April 14, 2020 • PHP

今天工作中遇到一个需要把服务器或者第三方云存储厂商上的图片进行base64编码以适应前端的组件,所以简单的看了下相关函数,故封装了一下。

因为PHP对Base64的支持非常好,有内置的base64_encodebase64_decode负责图片的Base64编码与解码。

编码上,只要将图片流读取到,而后使用base64_encode进行进行编码即可得到。

初版

/**
 * 获取图片的Base64编码(不支持url)
 * @author https://keer.me
 *
 * @param $img_file 传入本地图片地址
 *
 * @return string
 */
function imgToBase64($img_file) {

    $img_base64 = '';
    if (file_exists($img_file)) {
        $img_info = getimagesize($img_file); // 取得图片的大小,类型等

        $fp = fopen($img_file, "r"); // 图片是否可读权限

        if ($fp) {
            $filesize = filesize($img_file);
            $content = fread($fp, $filesize);
            $file_content = chunk_split(base64_encode($content)); // base64编码
            switch ($img_info[2]) {           //判读图片类型
                case 1: $img_type = "gif";
                    break;
                case 2: $img_type = "jpg";
                    break;
                case 3: $img_type = "png";
                    break;
            }

            $img_base64 = 'data:image/' . $img_type . ';base64,' . $file_content;//合成图片的base64编码

        }
        fclose($fp);
    }

    return $img_base64; //返回图片的base64
}


//调用使用的方法
$img_dir = dirname(__FILE__) . '/uploads/img/test.jpg';
$img_base64 = imgToBase64($img_dir);
echo '<img src="' . $img_base64 . '">';       //图片形式展示
echo '<hr>';
echo $img_base64;           //输出Base64编码

改进版

上面的版本不支持http协议的图片,比如一张图片https://u.vmpic.cn/2020/04/14/cBMU.png。此时使用filesize将获取不到文件大小。

这里我更加推荐使用PHP内置的file_get_contents函数,这个函数其实调用了fopen fread以及fclose一气呵成。

/**
 * 获取图片的Base64编码(支持url)
 * @author https://keer.me
 *
 * @param $img_file 传入本地图片地址
 *
 * @return string
 */
function imgToBase64($img_file) {
    if (empty($img_file)) {
        return '';
    }
    $img_info = getimagesize($img_file); // 取得图片的大小,类型等
    if (! $img_info) {
        return '';
    }
    $img_base64 = '';
    if (strpos($img_file, 'http') === false)
    {
        if (! file_exists($img_file)) {
            return '';
        }

        $fp = fopen($img_file, "r"); // 图片是否可读权限
        if ($fp) {
            $filesize = filesize($img_file);
            $content = fread($fp, $filesize);
            $file_content = chunk_split(base64_encode($content)); // base64编码
        }
        fclose($fp);
    }
    else
    {
        $file_content = base64_encode(file_get_contents($img_file));
    }

    switch ($img_info[2]) {           //判读图片类型
        case 1: $img_type = "gif";
            break;
        case 2: $img_type = "jpg";
            break;
        case 3: $img_type = "png";
            break;
    }
    $img_base64 = 'data:image/' . $img_type . ';base64,' . $file_content;//合成图片的base64编码

    return $img_base64; //返回图片的base64
}

调用方法参考:

$img_file = 'https://u.vmpic.cn/2020/04/14/cBMU.png';
$img_base64 = imgToBase64($img_file);
echo '<img src="' . $img_base64 . '">';       //图片形式展示
echo '<hr>';
echo $img_base64;           //输出Base64编码

更新: 2020-05-27

二进制流文件转换为Base64或本地文件

在对接微信小程序的时候,需要生成小程序码。这时候微信会直接已二进制流文件返回,所以对应记录一些流文件存回本地或者OSS上的方法,仅供参考。

  1. 二进制流转化为Base64格式图片

    $imgInfo = getimagesizefromstring($imageData)['mime']; 
    // array ( 0 => 430, 1 => 430, 2 => 2, 3 => 'width="430" height="430"', 'bits' => 8, 'channels' => 3, 'mime' => 'image/jpeg')
    
    $type = $imgInfo['mime']; //获取二进制流图片格式
    
    $base64String = 'data:' . $type . ';base64,' . chunk_split(base64_encode($imageData));
     
    //格式如:
    'data:image/png;base64,iVBORw0...此处省略...RZV0P=';
     
     
    //输出图片
    echo "<img src='{$base64String }'>";
  1. Base64格式图片转化为二进制流

    //截取data:image/png;base64, 这个逗号后的字符
    $array = explode(',', $base64String); 
     
    //对截取后的字符使用base64_decode进行解码,此为二进制流图片
    $imgData = base64_decode(end($array));  
    
  1. 二进制流转化为本地格式图片

    $file = "/opt/www/logo.png";
    file_put_contents( $file, $imgData);
  1. 图片文件转化成二进制流

    $image = 'E:/www/logo.png';  //图片文件地址
     
    $type = getimagesize($image)['mime'];    //获取图片类型
    $imgData = file_get_contents($image);    //获取图片二进制流
     
    //输出二进制图片
    ob_clean();    //清除缓冲区,防止出现“图像因其本身有错无法显示'的问题
    header("Content-Type:{$type}");
    echo $imgData; //输出图片
     
    //或者把此文件地址作为img标签src地址输出
    //<img src="imgdata.php">

php处理base64格式图片上传

$base64_image_content:要保存的Base64

$path:要保存的路径

public function base64_image_content($base64_image_content,$path){
        //匹配出图片的格式
        if (preg_match('/^(data:\s*image\/(\w+);base64,)/', $base64_image_content, $result)){
            $type = $result[2];
            //$ff=date('Y-m-d',time());
            $new_file = $path."/lunbo/";
            if(!file_exists($new_file)){
                //检查是否有该文件夹,如果没有就创建,并给予最高权限
                mkdir($new_file, 0700);
            }
            $picname=mt_rand(0,99).time().".{$type}";
            $new_file = $new_file.$picname;
            if (file_put_contents($new_file, base64_decode(str_replace($result[1], '', $base64_image_content)))){
                return "/Uploads/lunbo/".$picname;
            }else{
                return false;
            }
        }else{
            return false;
        }
    }

调用

$data['pic'] = $this->base64_image_content($_POST['thumb_url'],'./Uploads');

在来一个Laravel的参考

$avatar1 = Attachment::base64Image($avatar);
    protected static $max_size = 2048000;// 图片上传最大尺寸
    protected static $extension = ['jpg','jpeg','gif','bmp','png'];// 图片格式限制

    /**
     * @param string    $stream       base64图片流
     * @param   string  $sub_dir      上传upload子目录
     * @return bool|string
     */
    public static function base64Image($stream, $sub_dir='attachment', $auth = null)
    {
        $server = request()->server();
        if (preg_match('/^(data:\s*image\/(\w+);base64,)/', $stream,$result)){
            $type = $result[2];//图片后缀
            if(!in_array($type, self::$extension)){
                $auth && $auth->setError('上传文件格式不正确');
                return false;
            }
            $date = date('Ymd', time());
            $dir_name = $_SERVER['DOCUMENT_ROOT']."/uploads/$sub_dir/".$date.'/';
            if (!file_exists($dir_name)) {
                //检查是否有该文件夹,如果没有就创建,并给予最高权限
                $mk = mkdir($dir_name, 0700, true);
                if($mk === false){
                    $auth && $auth->setError('上传失败,没有权限');
                    return false;
                }
            }

            $filename = mt_rand(1000,9999) . '_' . uniqid() . ".{$type}"; //文件名
            $new_file = $dir_name . $filename;
            //写入操作
            $file_stream = base64_decode(str_replace($result[1], '', $stream));
            if(strlen($file_stream)/1024 > 4096){
                $auth && $auth->setError('文件太大,超过4M');
                return false;
            }
            if(file_put_contents($new_file, base64_decode(str_replace($result[1], '', $stream))) === false) {
                $auth && $auth->setError('服务器响应失败');
                return false;
            }else{
                return $server['REQUEST_SCHEME'] . '://' . $server['SERVER_NAME']. "/uploads/$sub_dir/".$date.'/' . $filename;
            }
        }else{
            $auth && $auth->setError('文件检测不合法');
            return false;
        }
    }
Last Modified: May 27, 2020