PHP检测PNG8或PNG24

标签 php png

我需要一种简单的方法来检测正在上传的 PNG 文件。我尝试了 getimagesize,但它返回 PNG8 和 PNG24 的第 8 位。

任何人都知道如何检测图像是 PNG8,也就是位深度为 8。谢谢!

最佳答案

试试这个来检测 PNG8、PNG24 和 PNG32:

<?php

$file = new SplFileObject('png8.png');

$realPath = $file->getRealPath();
if ($realPath === false) {
    throw new RuntimeException(sprintf('File not found: %s', $file->getFilename()));
}

$file->rewind();

if ($file->fread(4) !== chr(0x89) . 'PNG') {
    // This is not a PNG
    throw new RuntimeException(sprintf('Invalid PNG file: %s', $file->getFilename()));
}

$file->rewind();
$file->fread(8 + 4);
$idr = $file->fread(4);

// Make sure we have an IHDR
if ($idr !== 'IHDR') {
    throw new RuntimeException('No PNG IHDR header found, invalid PNG file.');
}

// PNG actually stores Width and height integers in big-endian.
$width = unpack('N', (string)$file->fread(4))[1];
$height = unpack('N', (string)$file->fread(4))[1];

// Bit depth: 1 byte
// Bit depth is a single-byte integer giving the number of bits per sample or
// per palette index (not per pixel).
//
// Valid values are 1, 2, 4, 8, and 16, although not all values are allowed for all color types.
$bitDepth = ord((string)$file->fread(1));

// Pixel format
// https://en.wikipedia.org/wiki/Portable_Network_Graphics#Pixel_format

// Color type is a single-byte integer that describes the interpretation of the image data.
// Color type codes represent sums of the following values:
// 1 (palette used), 2 (color used), and 4 (alpha channel used).
//
// Valid values are 0, 2, 3, 4, and 6.
$colorType = ord((string)$file->fread(1));

$colorTypes = [
    0 => 'Greyscale',
    2 => 'Truecolour',
    3 => 'Indexed-colour',
    4 => 'Greyscale with alpha',
    6 => 'Truecolour with alpha',
];

$colorTypeText = $colorTypes[$colorType];

$pngType = '?';
// If the bitdepth is 8 and the colortype is 3 (Indexed-colour) you have a PNG8
if ($bitDepth === 8 && $colorType === 3) {
    $pngType = 'PNG8';
}

// If the bitdepth is 8 and colortype is 2 (Truecolour) you have a PNG24.
if ($bitDepth === 8 && $colorType === 2) {
    $pngType = 'PNG24';
}

// If the bitdepth is 8 and colortype is 6 (Truecolour with alpha) you have a PNG32.
if ($bitDepth === 8 && $colorType === 6) {
    $pngType = 'PNG32';
}

echo sprintf('Width: %s, Height: %s, Bit-Depth: %s, Color-Type: %s (%s), Type: %s',
    $width,
    $height,
    $bitDepth,
    $colorType,
    $colorTypeText,
    $pngType
);

输出:

Width: 1500, Height: 500, Bit-Depth: 8, Color-Type: 3 (Indexed-colour), Type: PNG8

关于PHP检测PNG8或PNG24,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57547818/

相关文章:

php - 透明png上的渐变叠加

php - 从 jQuery AJAX 表单发布中获取未定义的响应

php - 使用 CSS 和 PHP 实现多语言

php - 如何在没有额外提供商的情况下通过 channel 管理器同步 MySQL 数据库(或我的网站预订)?

png - 为什么较小的 PNG 图像在通过 GraphicsMagic 调整大小后比原始图像占用更多空间

google-apps-script - 如何将 Google 幻灯片下载为图片?

rest - 使用 grails.plugins.rest.client.RestResponse 获取 img/png

php - 在js中推送数组看起来无法正常工作

php - Laravel 从数据库中返回用户最后一项

image - 使用 PictureRecorder 保存 Canvas 的图片导致图像为空