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 远程文件管理,可以给表格排序,遍历目录,时间排序
Aug 07 PHP
PHP闭包实例解析
Sep 08 PHP
两种php给图片加水印的实现代码
Apr 18 PHP
PHP实现长文章分页实例代码(附源码)
Feb 03 PHP
各种快递查询--Api接口
Apr 26 PHP
php实现文章置顶功能的方法
Oct 20 PHP
PHP函数rtrim()使用中的怪异现象分析
Feb 24 PHP
php读取XML的常见方法实例总结
Apr 25 PHP
CI框架(CodeIgniter)公共模型类定义与用法示例
Aug 10 PHP
PHP实现的最大正向匹配算法示例
Dec 19 PHP
总结PHP代码规范、流程规范、git规范
Jun 18 PHP
Thinkphp 在api开发中异常返回依然是html的解决方式
Oct 16 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
火影忍者:这才是千手柱间和扉间的真正死因,角都就比较搞笑了!
2020/03/10 日漫
sony ICF-2010 拆解与改装
2021/03/02 无线电
require(),include(),require_once()和include_once()的异同
2007/01/02 PHP
PHPExcel读取Excel文件的实现代码
2011/12/06 PHP
解析php防止form重复提交的方法
2013/07/01 PHP
PHP队列用法实例
2014/11/05 PHP
PHP实现支持加盐的图片加密解密
2016/09/09 PHP
Laravel Intervention/image图片处理扩展包的安装、使用与可能遇到的坑详解
2017/11/14 PHP
node.js中使用node-schedule实现定时任务实例
2014/06/03 Javascript
javascript中对象的定义、使用以及对象和原型链操作小结
2016/12/14 Javascript
Node.js Mongodb 密码特殊字符 @的解决方法
2017/04/11 Javascript
vue省市区三联动下拉选择组件的实现
2017/04/28 Javascript
vue中倒计时组件的实例代码
2018/07/06 Javascript
mpvue实现左侧导航与右侧内容的联动
2019/10/21 Javascript
[01:51]历届DOTA2国际邀请赛举办地回顾 TI9落地上海
2018/08/26 DOTA
Python日期操作学习笔记
2008/10/07 Python
详解python开发环境搭建
2016/12/16 Python
Python 字典与字符串的互转实例
2017/01/13 Python
python基础教程之匿名函数lambda
2017/01/17 Python
Python爬取网易云音乐热门评论
2017/03/31 Python
Python实现的科学计算器功能示例
2017/08/04 Python
Python3中关于cookie的创建与保存
2018/10/21 Python
对python实现二维函数高次拟合的示例详解
2018/12/29 Python
如何通过Python实现标签云算法
2019/07/02 Python
TensorFlow-gpu和opencv安装详细教程
2020/06/30 Python
戴尔美国官网:Dell
2016/08/31 全球购物
优秀员工个人的自我评价
2013/11/29 职场文书
职业生涯规划设计步骤
2014/01/12 职场文书
结婚邀请函范文
2014/01/14 职场文书
什么是就业协议书
2014/04/17 职场文书
作风建设整改方案
2014/10/27 职场文书
成本会计实训报告
2014/11/05 职场文书
优秀班主任事迹材料
2014/12/16 职场文书
职称评定个人总结
2015/03/05 职场文书
感恩节寄语2015
2015/03/24 职场文书
使用 DataAnt 监控 Apache APISIX的原理解析
2022/07/07 Servers