PHP处理bmp格式图片的方法分析


Posted in PHP onJuly 04, 2017

本文分析了PHP处理bmp格式图片的方法。分享给大家供大家参考,具体如下:

白天QA提出项目上传图片有问题,具体为:上传成功,预览失败。我去了之后,又上传了几张其他的图片可以上传,然后仔细问了下他上传的是哪张图片,看了后使用getimagesize函数打印了下。

Array
(
  [0] => 494
  [1] => 260
  [2] => 6
  [3] => width="494" height="260"
  [bits] => 24
  [mime] => image/x-ms-bmp
)

仔细看下,上面打印的数组,mime为image/x-ms-bmp,也就是bmp格式的,印象中php的gd库没有处理这个函数,后来我便在配置文件中,只要mime为这种的便不能上传。

晚上回来后,我便在网上查找php处理bmp相关方法,后来终于在stackoverflow中找到了,帖子里说进入官网的有关imagecreate的函数评论,有个ImageCreateFromBMP方法,先把bmp格式的文件给此函数调用,再用imagejpeg保存就行,后来试了下,发现imagepng也行,下面贴出代码。

<?php
function ImageCreateFromBMP($filename) {
  //Ouverture du fichier en mode binaire
  if (!$f1 = fopen($filename, "rb"))
    return FALSE;
  //1 : Chargement des ent�tes FICHIER
  $FILE = unpack("vfile_type/Vfile_size/Vreserved/Vbitmap_offset", fread($f1, 14));
  if ($FILE['file_type'] != 19778)
    return FALSE;
  //2 : Chargement des ent�tes BMP
  $BMP = unpack('Vheader_size/Vwidth/Vheight/vplanes/vbits_per_pixel' .
      '/Vcompression/Vsize_bitmap/Vhoriz_resolution' .
      '/Vvert_resolution/Vcolors_used/Vcolors_important', fread($f1, 40));
  $BMP['colors'] = pow(2, $BMP['bits_per_pixel']);
  if ($BMP['size_bitmap'] == 0)
    $BMP['size_bitmap'] = $FILE['file_size'] - $FILE['bitmap_offset'];
  $BMP['bytes_per_pixel'] = $BMP['bits_per_pixel'] / 8;
  $BMP['bytes_per_pixel2'] = ceil($BMP['bytes_per_pixel']);
  $BMP['decal'] = ($BMP['width'] * $BMP['bytes_per_pixel'] / 4);
  $BMP['decal'] -= floor($BMP['width'] * $BMP['bytes_per_pixel'] / 4);
  $BMP['decal'] = 4 - (4 * $BMP['decal']);
  if ($BMP['decal'] == 4)
    $BMP['decal'] = 0;
  //3 : Chargement des couleurs de la palette
  $PALETTE = array();
  if ($BMP['colors'] < 16777216) {
    $PALETTE = unpack('V' . $BMP['colors'], fread($f1, $BMP['colors'] * 4));
  }
  //4 : Cr�ation de l'image
  $IMG = fread($f1, $BMP['size_bitmap']);
  $VIDE = chr(0);
  $res = imagecreatetruecolor($BMP['width'], $BMP['height']);
  $P = 0;
  $Y = $BMP['height'] - 1;
  while ($Y >= 0) {
    $X = 0;
    while ($X < $BMP['width']) {
      if ($BMP['bits_per_pixel'] == 24)
        $COLOR = unpack("V", substr($IMG, $P, 3) . $VIDE);
      elseif ($BMP['bits_per_pixel'] == 16) {
        $COLOR = unpack("n", substr($IMG, $P, 2));
        $COLOR[1] = $PALETTE[$COLOR[1] + 1];
      } elseif ($BMP['bits_per_pixel'] == 8) {
        $COLOR = unpack("n", $VIDE . substr($IMG, $P, 1));
        $COLOR[1] = $PALETTE[$COLOR[1] + 1];
      } elseif ($BMP['bits_per_pixel'] == 4) {
        $COLOR = unpack("n", $VIDE . substr($IMG, floor($P), 1));
        if (($P * 2) % 2 == 0)
          $COLOR[1] = ($COLOR[1] >> 4);
        else
          $COLOR[1] = ($COLOR[1] & 0x0F);
        $COLOR[1] = $PALETTE[$COLOR[1] + 1];
      }
      elseif ($BMP['bits_per_pixel'] == 1) {
        $COLOR = unpack("n", $VIDE . substr($IMG, floor($P), 1));
        if (($P * 8) % 8 == 0)
          $COLOR[1] = $COLOR[1] >> 7;
        elseif (($P * 8) % 8 == 1)
          $COLOR[1] = ($COLOR[1] & 0x40) >> 6;
        elseif (($P * 8) % 8 == 2)
          $COLOR[1] = ($COLOR[1] & 0x20) >> 5;
        elseif (($P * 8) % 8 == 3)
          $COLOR[1] = ($COLOR[1] & 0x10) >> 4;
        elseif (($P * 8) % 8 == 4)
          $COLOR[1] = ($COLOR[1] & 0x8) >> 3;
        elseif (($P * 8) % 8 == 5)
          $COLOR[1] = ($COLOR[1] & 0x4) >> 2;
        elseif (($P * 8) % 8 == 6)
          $COLOR[1] = ($COLOR[1] & 0x2) >> 1;
        elseif (($P * 8) % 8 == 7)
          $COLOR[1] = ($COLOR[1] & 0x1);
        $COLOR[1] = $PALETTE[$COLOR[1] + 1];
      } else
        return FALSE;
      imagesetpixel($res, $X, $Y, $COLOR[1]);
      $X++;
      $P += $BMP['bytes_per_pixel'];
    }
    $Y--;
    $P+=$BMP['decal'];
  }
  //Fermeture du fichier
  fclose($f1);
  return $res;
}
$pic = '2.bmp';
$res = ImageCreateFromBMP($pic);
imagepng($res, '1.png');
imagejpeg($res, '1.jpeg');

希望本文所述对大家PHP程序设计有所帮助。

PHP 相关文章推荐
php 无极分类(递归)实现代码
Jan 05 PHP
php中邮箱地址正则表达式实现与详解
Apr 24 PHP
web目录下不应该存在多余的程序(安全考虑)
May 09 PHP
详解PHP中的状态模式编程
Aug 11 PHP
简介WordPress中用于获取首页和站点链接的PHP函数
Dec 17 PHP
PHP使用内置函数生成图片的方法详解
May 09 PHP
php字符串比较函数用法小结(strcmp,strcasecmp,strnatcmp及strnatcasecmp)
Jul 18 PHP
PHP图片水印类的封装
Jul 06 PHP
php+js实现裁剪任意形状图片
Oct 31 PHP
Centos7 Yum安装PHP7.2流程教程详解
Jul 02 PHP
Laravel基础_关于view共享数据的示例讲解
Oct 14 PHP
PHP7 参数处理机制修改
Mar 09 PHP
PHP实现对文件锁进行加锁、解锁操作的方法
Jul 04 #PHP
PHP利用Cookie设置用户30分钟未操作自动退出功能
Jul 03 #PHP
PHP错误处理函数register_shutdown_function使用示例
Jul 03 #PHP
PHP使用preg_split和explode分割textarea存放内容的方法分析
Jul 03 #PHP
PHP简单获取上月、本月、近15天、近30天的方法示例
Jul 03 #PHP
thinkPHP多表查询及分页功能实现方法示例
Jul 03 #PHP
PHP+Ajax实现的无刷新分页功能详解【附demo源码下载】
Jul 03 #PHP
You might like
谈谈PHP语法(4)
2006/10/09 PHP
用php将任何格式视频转为flv的代码
2009/09/03 PHP
PHP 自定义错误处理函数的使用详解
2013/05/10 PHP
php+mysqli批量查询多张表数据的方法
2015/01/29 PHP
Zend Framework教程之Zend_Config_Ini用法分析
2016/03/23 PHP
PHP实现蛇形矩阵,回环矩阵及数字螺旋矩阵的方法分析
2017/05/29 PHP
Nigma vs Liquid BO3 第一场2.13
2021/03/10 DOTA
HTTP状态代码以及定义(解释)
2007/02/02 Javascript
前台js改变Session的值(用ajax实现)
2012/12/28 Javascript
ListBox实现上移,下移,左移,右移的简单实例
2014/02/13 Javascript
如何让你的Lightbox支持滚轮缩放及Base64图片
2014/12/04 Javascript
深入学习JavaScript中的Rest参数和参数默认值
2015/07/28 Javascript
JavaScript DOM 学习总结(五)
2015/11/24 Javascript
论Bootstrap3和Foundation5网格系统的异同
2016/05/16 Javascript
详解Vue.js动态绑定class
2016/12/20 Javascript
yarn的使用与升级Node.js的方法详解
2017/06/04 Javascript
Angular中自定义Debounce Click指令防止重复点击
2017/07/26 Javascript
浅谈vue的props,data,computed变化对组件更新的影响
2018/01/16 Javascript
JavaScript页面加载事件实例讲解
2019/09/01 Javascript
Python2.5/2.6实用教程 入门基础篇
2009/11/29 Python
零基础学Python(一)Python环境安装
2014/08/20 Python
使用Python和xlwt向Excel文件中写入中文的实例
2018/04/21 Python
Python检测数据类型的方法总结
2019/05/20 Python
python设计tcp数据包协议类的例子
2019/07/23 Python
解决Pycharm中恢复被exclude的项目问题(pycharm source root)
2020/02/14 Python
python实现爱奇艺登陆密码RSA加密的方法示例详解
2020/05/27 Python
详解pyqt5的UI中嵌入matplotlib图形并实时刷新(挖坑和填坑)
2020/08/07 Python
Python虚拟环境virtualenv创建及使用过程图解
2020/12/08 Python
HTML5 常见面试题之PC端和移动端区别介绍
2018/01/22 HTML / CSS
基于Html5实现的语音搜索功能
2019/05/13 HTML / CSS
中国专业的综合网上购物商城:京东
2016/08/02 全球购物
机关办公室岗位职责
2014/04/16 职场文书
2014年医药代表工作总结
2014/11/22 职场文书
单独二胎证明
2015/06/24 职场文书
解决Vue+SpringBoot+Shiro跨域问题
2021/06/09 Vue.js
Mybatis-plus配置分页插件返回统一结果集
2022/06/21 Java/Android