1

この時点で、this-thing.pngという画像 ( Photoshop CS5から PNG24 として作成) がkcfinderとしてアップロードされることに非常に混乱していimage/jpegます。

ここに画像の説明を入力

TriIDで分析すると、画像が完全に 100% PNG であることがわかります

C:\TrID>trid C:\users\michael\downloads\this-thing.png

TrID/32 - File Identifier v2.20 - (C) 2003-15 By M.Pontello
Definitions found:  3790
Analyzing...

Collecting data from file: C:\users\michael\downloads\this-thing.png
100.0% (.PNG) Portable Network Graphics (16000/1)

しかし、$_FILES[(key($_FILES)]['tmp_name']内の変数 dataがkcfinder\core\class\browser.php関数moveUploadFile (引数$fileとして) に到達すると ... tmp_name からの MIME タイプPNG ではなく JPEG として表示されます。

テスト目的で変更された関数には、false を返さない getimagesize()からのコードが含まれていました

protected function moveUploadFile($file, $dir) {

    $message = $this->checkUploadedFile($file);

    if ($message !== true) {
        if (isset($file['tmp_name']))
            @unlink($file['tmp_name']);
        return "{$file['name']}: $message";
    }

    $filename = $this->normalizeFilename($file['name']);
    $target = "$dir/" . file::getInexistantFilename($filename, $dir);

    echo "<h3>PHP_FILES foreach</h3>";

    foreach ($_FILES['upload']['name'] as $key => $value){    
        echo "<pre>";
        print_r(getimagesize($_FILES['upload']['tmp_name'][$key]));
        echo "</pre>";
    }

    echo "<h3>TEMP FILE</h3>";
    echo "</strong>file variable</strong>";
    echo "<pre>";
    print_r($file);
    echo "</pre>";

    echo "</strong>file.tmp_name</strong>";
    echo "<pre>";
    print_r($file['tmp_name']);
    echo "</pre>";

    $tmp_name_imagesize = getimagesize($file['tmp_name']);

    echo "<pre>";
    print_r($tmp_name_imagesize);
    echo "</pre>";

    if (imagetypes() & IMG_PNG) { echo "PNG Supported"; } else { echo "PNG not supported."; }

    // mkaatman - move tmp file to /tmp/ to check its MD5SUM result
    $temporary_file_path = $file['tmp_name'] . ".uploaded";
    move_uploaded_file($file['tmp_name'], $temporary_file_path);

    die();

}

ファイルthis-thing.pngのアップロード中の結果は、メディア タイプが実際にはPNGではなくJPGであることを示しています(これは一部であり、頭を包むことができないようです)。

ここに画像の説明を入力
(出典: iforce.co.nz )

どうやらこのファイルphp92C2.tmp.uploadedは、/tmp/ディレクトリにアップロードされたファイルです。

ここに画像の説明を入力

ファイル分析の目的で.png、を使用して、ファイルの末尾に追加しました。Windows Rename

C:\TrID>trid C:\users\michael\downloads\php92C2.tmp.uploaded.png

TrID/32 - File Identifier v2.20 - (C) 2003-15 By M.Pontello
Definitions found:  3790
Analyzing...

Collecting data from file: C:\users\michael\downloads\php92C2.tmp.uploaded.png
 50.0% (.JPG) JFIF JPEG Bitmap (4003/3)
 37.4% (.JPG) JPEG Bitmap (3000/1)
 12.4% (.MP3) MP3 audio (1000/1)

ただし、イメージが PHP を介して直接テストされている場合 (コピーしてディレクトリに貼り付けます)

<?php

$image_file = "this-thing.png";
$image_file_details = getimagesize($image_file);

echo "<pre>";
print_r($image_file_details);
echo "</pre>";

?>

その結果、画像が実際には PNG であることがわかります。

Array
(
    [0] => 800
    [1] => 300
    [2] => 3
    [3] => width="800" height="300"
    [bits] => 8
    [mime] => image/png
)

kcfinder/cache/base.js関数function _.initUploadButton = function()内で使用されるフォームは、基本的なアップロード フォームです。

<div id="upload" style="top:5px;width:77px;height:31px">
    <form enctype="multipart/form-data" method="post" target="uploadResponse" action="browse.php?type=image&lng=en&opener=ckeditor&act=upload"><input type="file" name="upload[]" onchange="_.uploadFile(this.form)" style="height:31px" multiple="multiple" /><input type="hidden" name="dir" value="" /></form>
</div>

最後に、KCFINDER.Config からの情報php

CONFIG.imageDriversPriority

imagick gmagick gd

CONFIG.deniedExts

exe com msi bat php phps phtml php3 php4 cgi pl htaccess htm html

CONFIG.types

Array
(
    [image] => 7z aiff asf avi bmp csv doc fla flv gif gz gzip jpeg jpg mid mov mp3 mp4 mpc mpeg mpg ods odt pdf png ppt pxd qt ram rar rm rmi rmvb rtf sdc sitd swf sxc sxw tar tgz tif tiff txt vsd wav wma wmv xls xml zip
    [images] => 7z aiff asf avi bmp csv doc fla flv gif gz gzip jpeg jpg mid mov mp3 mp4 mpc mpeg mpg ods odt pdf png ppt pxd qt ram rar rm rmi rmvb rtf sdc sitd swf sxc sxw tar tgz tif tiff txt vsd wav wma wmv xls xml zip
    [files] => 7z aiff asf avi bmp csv doc fla flv gif gz gzip jpeg jpg mid mov mp3 mp4 mpc mpeg mpg ods odt pdf png ppt pxd qt ram rar rm rmi rmvb rtf sdc sitd swf sxc sxw tar tgz tif tiff txt vsd wav wma wmv xls xml zip
    [uploads] => 7z aiff asf avi bmp csv doc fla flv gif gz gzip jpeg jpg mid mov mp3 mp4 mpc mpeg mpg ods odt pdf png ppt pxd qt ram rar rm rmi rmvb rtf sdc sitd swf sxc sxw tar tgz tif tiff txt vsd wav wma wmv xls xml zip
    [mimages] => *mime image/gif image/png image/jpeg
)

このすべての情報に基づいて、PNG としてアップロードされた画像がなぜ JPEG として戻ってくるのか理解できないようです。

編集:mspaintから作成された画像を使用してkcfinderをテストしました(これが混乱を招く場所です)

テストした PNG 画像。

ここに画像の説明を入力

結果 (上記のコードに基づく)。

ここに画像の説明を入力

C:\TrID>trid C:\users\michael\Pictures\breaking-bad.png

TrID/32 - File Identifier v2.20 - (C) 2003-15 By M.Pontello
Definitions found:  3790
Analyzing...

Collecting data from file: C:\users\michael\Pictures\breaking-bad.png
100.0% (.PNG) Portable Network Graphics (16000/1)

C:\TrID>

編集: PNG のサポート (markman への返信)

if (imagetypes() & IMG_PNG) {
    echo "PNG Supported";
} else {
    echo "PNG not supported.";
}

編集:画像がPNGからJPGに変換されている場所を見つけました

ファイルcheckUploadedFile中にコメントアウトされている場合は、期待どおりのPNGとして出力されます....moveUploadFilethis-thing.png

protected function checkUploadedFile(array $aFile=null) {
    $config = &$this->config;
    $file = ($aFile === null) ? $this->file : $aFile;

    if (!is_array($file) || !isset($file['name']))
        return $this->label("Unknown error");

    if (is_array($file['name'])) {
        foreach ($file['name'] as $i => $name) {
            $return = $this->checkUploadedFile(array(
                'name' => $name,
                'tmp_name' => $file['tmp_name'][$i],
                'error' => $file['error'][$i]
            ));
            if ($return !== true)
                return "$name: $return";
        }
        return true;
    }

    $extension = file::getExtension($file['name']);
    $typePatt = strtolower(text::clearWhitespaces($this->types[$this->type]));

    // CHECK FOR UPLOAD ERRORS
    if ($file['error'])
        return
            ($file['error'] == UPLOAD_ERR_INI_SIZE) ?
                $this->label("The uploaded file exceeds {size} bytes.",
                    array('size' => ini_get('upload_max_filesize'))) : (
            ($file['error'] == UPLOAD_ERR_FORM_SIZE) ?
                $this->label("The uploaded file exceeds {size} bytes.",
                    array('size' => $_GET['MAX_FILE_SIZE'])) : (
            ($file['error'] == UPLOAD_ERR_PARTIAL) ?
                $this->label("The uploaded file was only partially uploaded.") : (
            ($file['error'] == UPLOAD_ERR_NO_FILE) ?
                $this->label("No file was uploaded.") : (
            ($file['error'] == UPLOAD_ERR_NO_TMP_DIR) ?
                $this->label("Missing a temporary folder.") : (
            ($file['error'] == UPLOAD_ERR_CANT_WRITE) ?
                $this->label("Failed to write file.") :
                $this->label("Unknown error.")
        )))));

    // HIDDEN FILENAMES CHECK
    elseif (substr($file['name'], 0, 1) == ".")
        return $this->label("File name shouldn't begins with '.'");

    // EXTENSION CHECK
    elseif (
        (substr($file['name'], -1) == ".") ||
        !$this->validateExtension($extension, $this->type)
    )
        return $this->label("Denied file extension.");

    // SPECIAL DIRECTORY TYPES CHECK (e.g. *img)
    elseif (preg_match('/^\*([^ ]+)(.*)?$/s', $typePatt, $patt)) {
        list($typePatt, $type, $params) = $patt;
        $class = __NAMESPACE__ . "\\type_$type";
        if (class_exists($class)) {
            $type = new $class();
            $cfg = $config;
            $cfg['filename'] = $file['name'];
            if (strlen($params))
                $cfg['params'] = trim($params);
            $response = $type->checkFile($file['tmp_name'], $cfg);
            if ($response !== true)
                return $this->label($response);
        } else
            return $this->label("Non-existing directory type.");
    }

    // IMAGE RESIZE
    $img = image::factory($this->imageDriver, $file['tmp_name']);
    if (!$img->initError && !$this->imageResize($img, $file['tmp_name']))
        return $this->label("The image is too big and/or cannot be resized.");

    return true;
}

出力はPNG Supported.

4

1 に答える 1

0

これはかなり紛らわしい問題でした。しかし、私はそれを修正することができました。

必要な手順は次のとおりです。

ファイルを開き、kcfinder/core/class/uploader.php関数を見つけますimageResize。次に、this.outputコードを変更します。

前:

    // WRITE TO FILE
    return $img->output("jpeg", array(
        'file' => $file,
        'quality' => $this->config['jpegQuality']
    ));

後:

    // Check the EXTENSION OF THIS FILE
    if($file && is_string($file) && file_exists($file)) {
        $file_imgsize = @getimagesize($file);
        // Get the EXPECTED EXTENSION from this MIME
        if($file_imgsize && !empty($file_imgsize)) {
            $fileMimeInteger = $file_imgsize[2];
            $outputFileExtension = @image_type_to_extension($fileMimeInteger);
            $outputFileExtension = str_replace('.', '', $outputFileExtension);
        }
    }

    // Force Jpeg
    if(!$outputFileExtension) {
        $outputFileExtension = "jpeg";
    }

    // WRITE TO FILE
    return $img->output($outputFileExtension, array(
        'file' => $file,
        'quality' => $this->config['jpegQuality']
    ));

関数:

protected function imageResize($image, $file=null) {

        if (!($image instanceof image)) {
            $img = image::factory($this->imageDriver, $image);
            if ($img->initError) return false;
            $file = $image;
        } elseif ($file === null) {
             return false;
        }
        else {
            $img = $image;
        }

        $orientation = 1;
        if (function_exists("exif_read_data")) {
            $orientation = @exif_read_data($file);
            $orientation = isset($orientation['Orientation']) ? $orientation['Orientation'] : 1;
        }

        // IMAGE WILL NOT BE RESIZED WHEN NO WATERMARK AND SIZE IS ACCEPTABLE
        if ((
                !isset($this->config['watermark']['file']) ||
                (!strlen(trim($this->config['watermark']['file'])))
            ) && (
                (
                    !$this->config['maxImageWidth'] &&
                    !$this->config['maxImageHeight']
                ) || (
                    ($img->width <= $this->config['maxImageWidth']) &&
                    ($img->height <= $this->config['maxImageHeight'])
                )
            ) &&
            ($orientation == 1)
        )
            return true;

        // PROPORTIONAL RESIZE
        if ((!$this->config['maxImageWidth'] || !$this->config['maxImageHeight'])) {

            if ($this->config['maxImageWidth'] &&
                ($this->config['maxImageWidth'] < $img->width)
            ) {
                $width = $this->config['maxImageWidth'];
                $height = $img->getPropHeight($width);

            } elseif (
                $this->config['maxImageHeight'] &&
                ($this->config['maxImageHeight'] < $img->height)
            ) {
                $height = $this->config['maxImageHeight'];
                $width = $img->getPropWidth($height);
            }

            if (isset($width) && isset($height) && !$img->resize($width, $height))
                return false;

        // RESIZE TO FIT
        } elseif (
            $this->config['maxImageWidth'] && $this->config['maxImageHeight'] &&
            !$img->resizeFit($this->config['maxImageWidth'], $this->config['maxImageHeight'])
        )
            return false;

        // AUTO FLIP AND ROTATE FROM EXIF
        if ((($orientation == 2) && !$img->flipHorizontal()) ||
            (($orientation == 3) && !$img->rotate(180)) ||
            (($orientation == 4) && !$img->flipVertical()) ||
            (($orientation == 5) && (!$img->flipVertical() || !$img->rotate(90))) ||
            (($orientation == 6) && !$img->rotate(90)) ||
            (($orientation == 7) && (!$img->flipHorizontal() || !$img->rotate(90))) ||
            (($orientation == 8) && !$img->rotate(270))
        )
            return false;
        if (($orientation >= 2) && ($orientation <= 8) && ($this->imageDriver == "imagick"))
            try {
                $img->image->setImageProperty('exif:Orientation', "1");
            } catch (\Exception $e) {}

        // WATERMARK
        if (isset($this->config['watermark']['file']) &&
            is_file($this->config['watermark']['file'])
        ) {
            $left = isset($this->config['watermark']['left'])
                ? $this->config['watermark']['left'] : false;
            $top = isset($this->config['watermark']['top'])
                ? $this->config['watermark']['top'] : false;
            $img->watermark($this->config['watermark']['file'], $left, $top);
        }

        // Check the EXTENSION OF THIS FILE
        if($file && is_string($file) && file_exists($file)) {
            $file_imgsize = @getimagesize($file);
            // Get the EXPECTED EXTENSION from this MIME
            if($file_imgsize && !empty($file_imgsize)) {
                $fileMimeInteger = $file_imgsize[2];
                $outputFileExtension = @image_type_to_extension($fileMimeInteger);
                $outputFileExtension = str_replace('.', '', $outputFileExtension);
            }
        }

        // Force Jpeg
        if(!$outputFileExtension) {
            $outputFileExtension = "jpeg";
        }

        // WRITE TO FILE
        return $img->output($outputFileExtension, array(
            'file' => $file,
            'quality' => $this->config['jpegQuality']
        ));

    }

class_image_gd.php次に、関数のパス内のファイルをkcfinder/lib/class_image_gd.php探して、 がどのように機能output_pngするかを変更しますquality(これにより、「圧縮は 0-9 の間である必要があります」という PHP 関連のエラーが修正されます)。

protected function output_png(array $options=array()) {
    $file = isset($options['file']) ? $options['file'] : null;
    $quality = isset($options['quality']) ? $options['quality'] : null;
    $filters = isset($options['filters']) ? $options['filters'] : null;

    if (($file === null) && !headers_sent()) {
        header("Content-Type: image/png");
    }

    // Compression must be between 0-9 - 2/02/2016
    if($quality && is_numeric($quality)) {
        $quality = $quality < 100 ? round(($quality / 100) * 10) : null; 
    } else {
        $quality = null;
    }

    return imagepng($this->image, $file, $quality, $filters);
}

結果:

ここに画像の説明を入力
(出典: iforce.co.nz )

于 2016-02-04T03:16:23.830 に答える