prowebber / pure_image
一个简单的PHP图像格式化脚本
README
一个仅使用PHP编写的脚本,可简化图像自动压缩、调整大小和裁剪的过程。此脚本使用PHP和PHP GD的本地函数来压缩和调整图像大小。以下是Pure Image的主要优势:
- 处理图像类型转换(例如,将.png转换为.jpg)
- 在缩放时保持原始图像的宽高比
- 检测并修复无法被指定宽高整除的宽高比的图像
- 为每个图像生成哈希指纹以检测重复项
一般
安装
使用composer安装: composer require prowebber/pure_image
要求
在使用之前必须满足以下要求
- PHP >=7.3
- PHP GD (https://php.ac.cn/manual/en/book.image.php)
支持的图像
Pure Image可以读取、写入并在以下图像格式之间进行转换
- Gif (.gif)
- Jpeg (.jpg, .jpeg)
- Png (.png)
基本用法
Pure Image易于使用,只需4个步骤
- 调用init Pure Image
- 指定要压缩和/或调整大小的源图像
- 指定输出图像和压缩设置
- 保存图像
步骤1)实例化Pure Image
require_once __DIR__ . 'path_to_composer/autoload.php'; $pimage = new pure_image\PureImage();
步骤2)指定源图像
Pure Image对所有操作都需要源图像。您可以通过指定要压缩/调整大小的图像的完整路径来完成此操作。
$pimage->add->image('/abs_path/image.jpg');
步骤3)指定输出图像
在此处,您指定调整大小方法、输出图像的名称和位置以及如果需要还可以指定附加参数。
$pimage->out->compress([ 'save_path' => '/output_dir/file_name.jpg', ]);
步骤4)运行Pure Image
最后一步是运行脚本。这将执行所有操作,并将压缩/调整大小的图像保存到您在步骤3中指定的位置。
$pimage->save->image();
常见设置
调整大小选项/方法
图像压缩/质量
图像压缩的指定范围是0到5,1表示压缩最少(文件大小最大/质量最好),5表示压缩最多(文件大小最小/质量最差)。如果您留空压缩设置或将其设置为0
,脚本将回退到默认值。
Pure Image方法
以下是Pure Image格式输出图像的不同方式
- 压缩 - 仅压缩图像。不要缩放或调整大小。
- 覆盖 - 调整大小并裁剪输出图像,使其正好符合指定的宽度和高度。
- 适合 - 调整大小输出图像,使其适合指定的尺寸,同时保持宽高比。
- 缩放 - 创建指定宽度或高度的图像。保持宽高比。
压缩
压缩图像。不要缩放或调整大小输出图像。
选项 您可以在所有类型的方法中使用这些选项。
示例请求
$pimage = new pure_image\PureImage(); $pimage->add->image('/home/user/original.jpg'); $pimage->out->compress([ 'quality' => 3, 'save_path' => '/home/user/resized.jpg, ]); $pimage->save->image();
覆盖
图像调整大小到指定的确切宽度和高度。如果无法在指定大小下保持原始宽高比,则图像将被裁剪。
选项
示例请求
$pimage = new pure_image\PureImage(); $pimage->add->image('/home/user/original.jpg'); $pimage->out->cover([ 'width' => 250, 'height' => 250, 'quality' => 3, 'save_path' => '/home/user/resized.jpg, ]); $pimage->save->image();
适合
图像调整大小,使宽度和高度都适合指定的尺寸。输出图像将保持原始宽高比。
选项
示例代码
$pimage = new pure_image\PureImage(); $pimage->add->image('/home/user/original.jpg'); $pimage->out->fit([ 'width' => 250, 'height' => 250, 'quality' => 3, 'save_path' => '/home/user/resized.jpg, ]); $pimage->save->image();
缩放
根据图像的宽度或高度进行缩放。最终图像将精确到指定的宽度或高度,并保持原始的纵横比。
选项
示例请求
$pimage = new pure_image\PureImage(); $pimage->add->image('/home/user/original.jpg'); $pimage->out->scale([ 'width' => 250, 'height' => 250, 'quality' => 3, 'save_path' => '/home/user/resized.jpg, ]); $pimage->save->image();
哈希
哈希功能用于为每个图像创建唯一的哈希值,便于在数据库中检测重复的图像。所有哈希值具有以下特性
- 生成一个64字符的指纹,可以与其他图像进行比较
- 使用两种不同的哈希算法(平均和差异)
- 所有图像都被旋转,因此镜像图像将具有相同的哈希值
注意
- PHP不支持无符号BigInt,因此您需要在脚本中将指纹哈希转换为十六进制或十进制
- 您可以保存哈希图像(如果需要),但这不是必需的,因为指纹精确地表示图像
- 指纹中的每个数字都代表图像中的一个特定像素。0 = x0,y0,而63 = x7,y7
平均指纹
根据图像的平均亮度创建哈希值。
- 按顺序遍历每个像素
- 将当前像素的亮度与整个图像的平均亮度进行比较
- 如果当前像素比平均暗,则给当前像素赋值为
1
- 如果当前像素比平均亮,则给当前像素赋值为
0
- 如果当前像素比平均暗,则给当前像素赋值为
- 完成时,您将得到一个由0和1组成的64字符二进制字符串
差异指纹
基于前一个像素的亮度创建哈希值。
- 按顺序遍历每个像素
- 将当前像素的亮度与前一个像素的亮度进行比较
- 如果当前像素比前一个像素亮,则给当前像素赋值为
1
- 如果前一个像素比当前像素亮,则给当前像素赋值为
0
- 如果当前像素比前一个像素亮,则给当前像素赋值为
- 完成时,您将得到一个由0和1组成的64字符二进制字符串
这用于生成图像的哈希值,以帮助检测正在压缩的相似图像。哈希将执行以下操作
- 创建图像的16px x 16px黑白变体
- 以相同的方式旋转图像,以便发现翻转/旋转变体
- 生成图像的64位二进制值
- 使用二进制值创建十六进制和大整数值
数据库存储 您可以将图像哈希值存储在数据库中。以下是存储哈希值的MySQL表示例
问题
- PHP不支持无符号BigInt值
- 如果图像位值大于BigInt,则哈希值无效
- 最好的解决方案是使用位值,并让MySQL将其转换为BigInt哈希
- 更多SQL技巧即将到来
- This will convert the binary string to an Unsigned BigInt in MySQL SELECT CAST(CONV(BINARY('1000000110000000000000000000000000000001111011111111111111111111'), 2, 10) AS UNSIGNED INTEGER) img_hash
使用的哈希逻辑
1. Make all images uniform
|-- Shrink the image to 16px x 16px (use the 'cover' resize method)
|-- Convert the image to grayscale
2. Remove minor color differences
|-- Determine the overall average grayscale color value for the image
|-- Loop through each pixel and assign it a boolean grayscale value
| |-- Value of 1 indicates the pixel is darker than the average grayscale value
| |-- Value of 0 indicates the pixel is lighter than the average grayscale value
3. Rotate the image so the darkest size is on the bottom right and lightest side is top left
| |-- This helps catch similar images that are flipped or rotated
| |-- Convert the image from greyscale to only black or white values
| |-- Rotate the image
4. Compute the bits
|-- Resize the hash image to 8px x 8px so the total pixels is exactly 64
|-- Visit each pixel (since it has been rotated they may be different) and get the boolean grayscale value
|-- Assign black pixels to 1 and white pixels to 0
|-- Build the binary string of 0 and 1 values
5. Generate the hashes
|-- Record the binary string hash
|-- Record the Decimal/BigInt value of the binary string
|-- Record the hex value of the binary string
高级
创建多个输出图像
您可以通过对$pimage->out
方法进行额外的调用来创建多个输出图像,并传递所需的参数。当您准备好创建图像时,只需调用$pimage->save->images()
方法,它将创建所有图像。
$pimage->add->image('/home/user/original.jpg'); // Compress the image $pimage->out->compress([ 'quality' => 3, 'save_path' => '/home/user/compressed.jpg, ]); // Create an image to fit the specified params $pimage->out->fit([ 'width' => 300, 'height' => 200, 'quality' => 3, 'save_path' => '/home/user/resized.jpg, ]); // Create another image to fit the specified params $pimage->out->fit([ 'width' => 600, 'height' => 400, 'quality' => 3, 'save_path' => '/home/user/resized.jpg, ]); // Create all images $pimage->save->image();
自定义设置
以下是您可以设置和/或动态更改的设置。
允许的最大图像大小
这设置了源图像可以接受的最大大小(以字节为单位)。如果超出此图像大小,则会抛出错误。
$pimage->setMaxImageSize(10000000);
获取输出结果
创建图像后,您可以使用以下方法调用获取输出结果/响应
$result = $pimage->getResult();
这将返回一个包含每个处理图像详细信息的数组。如果您为每个图像指定了唯一的ID,则响应数组将按该ID键入。如果您没有为每个图像指定ID,则响应数组从0
开始,并将随每个附加输出图像递增。因此,请求$result[0]
将返回该图像的调试信息。
错误
纯图像id设计用于在生成任何输出图像之前捕捉所有错误。如果检测到错误,它
将存储错误信息并返回false。以下是检查错误的不同方式
按ID错误
这些是纯图像检查的错误代码(和错误)。
检查是否存在错误
以下代码将返回TRUE
如果没有错误;如果有错误则返回FALSE
。
$pimage->isErrorFree();
将错误输出到屏幕
如果存在错误,这将把它们输出/转储到屏幕上。
$pimage->showErrors();
返回错误数组
如果存在错误,这将返回包含错误的关联数组。键/索引将是错误信息的MD5值。
$pimage->getErrors();
返回详细错误数组
您可以通过以下方法调用返回详细错误数组(按图像ID键入)
$pimage->getDetailedErrors();
这将返回一个数组,其语法如下:上表中的每个$err_id
。
array[$image_id][$err_id] = Error message;
调试
您可以通过运行以下命令查看调试信息,该命令将所有调试信息转储到屏幕上。
$pimage->showDebug();
调试描述
以下是调试时输出的信息概览。
[ID] ** {Int} The Array index of the output image starting at 0
|-- method ** {String} The compression/resize method to use
|-- width_px ** {Int} The desired width of the output image
|-- height_px ** {Int} The desired height of the output image
|-- quality ** {Int} Quality level (converted to jpeg/png compression value)
|-- save_as ** {Array} Contains details on saving the image
| |-- file_type ** {String} jpg|png|gif
| |-- img_name ** {String} saved image name (e.g. mount-everest)
| |-- file_name ** {String} saved image filename (e.g. mount-everest.jpg)
| |-- file_path ** {String} saved image output path (e.g. /home/user/mount-everest.jpg)
|-- hash ** {Array} Contains hash details about the image (if selected as method)
| |-- avg_grey ** {Int} The average greyscale color for the image (0-255)
| |-- darkest ** {Array} Contains details of the darkest coordinates on the image
| | |-- vertical ** {String} The darkest vertical region in the image
| | |-- horizontal ** {String} The darkest horizontal region in the image
| |-- flip_direction ** {String} The direction the image was rotated before computing the hash
| |-- fingerprints ** {Array} Contains hash fingerprints
| | |-- average_hash ** {String} 64 character hash of pixel differences by average pixel color
| | |-- average_bit_count ** {Int} Total true bits in the average hash
| | |-- difference_hash ** {String} 64 character hash of pixel differences by previous pixel color
| | |-- difference_bit_count ** {Int} Total true bits in the difference hash
|-- rules ** {Array} Contains rules used for resizing the image
| |-- is_crop_needed ** {Bool} True if the image needs to be cropped to meet desired dimensions
| |-- longest_side ** {Array} Contains information on the input/output longest side(s)
| | |-- source ** {String} Which side on the source is the longest (width|height)
| | |-- source_px ** {Int} The length of the longest side in px
| | |-- output ** {String} Which side on the output is the longest (width|height)
| | |-- output_px ** {Int} The length of the longest side in px
| |-- calc_dimensions ** {Array} Contains dimensions required to keep the aspect ratio
| | |-- ratio ** {Int|Decimal} The ratio of the source to output image
| | |-- width ** {Int|Decimal} The width in px required for perfect fit
| | |-- height ** {Int|Decimal} The height in px required for perfect fit
| |-- resize ** {Array} Contains dimensions to re-size the image to
| | |-- width ** {Int} The width in px to resize the image to
| | |-- height ** {Int} The height in px to resize the image to
| |-- crop ** {Array} Contains crop details (if the image needs to be cropped)
| | |-- x ** {Int} Starting x-coord for the crop
| | |-- y ** {Int} Starting y-coord for the crop
| | |-- width ** {Int} Width of the crop
| | |-- height ** {Int} Height of the crop
| | |-- crop_position ** {String} Describes crop position {x y}
用法示例
示例1
这是目前在生产中用于添加图像的完整过程。
# Init pImage $pImage = new PureImage(); # Add the image $pImage->add->image('path/to/image.jpg'); # Check for errors triggered when the image was added if(!$pImage->isErrorFree()){ # If there are errors }