图像中的PHP图片部分(CROP)

Posted

技术标签:

【中文标题】图像中的PHP图片部分(CROP)【英文标题】:PHP picture parts from image (CROP) 【发布时间】:2014-10-14 10:39:48 【问题描述】:

您好,我有很大的技术问题,我需要将图像裁剪成这样的部分:

一个部分是 500px x 500px,除非空间较小。

示例图像大小为 1920 像素 x 1080 像素,我有 12 个图像部分。

我的问题是,我有 非常大的图像,它是 30 000 像素 x 20 000 像素,大​​约有 2800 部分

我尝试使用 php imagemagic 库

imagemagic 命令行代码:http://www.ioncannon.net/linux/81/5-imagemagick-command-line-examples-part-1/

使用此命令我可以裁剪图像位置:convert flower.jpg -crop 500×500+0+0 flower_crop.jpg

第一个和第二个参数部分的宽度高度:500;

第三个和第四个参数是从开始剪辑的位置开始的;

如果我需要得到大约 2800 个部件,我测试了每 20 秒裁剪一个部件:2800 x 20 / 60 / 60 = 15-16~ hours 我需要得到最快的结果。我该怎么做..

完整的php代码:

public function cutImgIntoPieces($imgPieceSizeWidth, $imgPieceSizeHeight, $outputDir) 
    $pieceWidth = $imgPieceSizeWidth;
    $pieceHeight = $imgPieceSizeHeight;

    $divWidth = floor($this->getImgWidth() / $pieceWidth);
    $modWidth = $this->getImgWidth() % $pieceWidth;
    $divHeight = floor($this->getImgHeight() / $pieceHeight);
    $modHeight = $this->getImgHeight() % $pieceHeight;

    for ($i = 0; $i <= $divWidth; $i++) 
        for ($j = 0; $j <= $divHeight; $j++) 

            $pieceWidth = ($i == $divWidth ? $modWidth : $imgPieceSizeWidth);
            $pieceHeight = ($j == $divHeight ? $modHeight : $imgPieceSizeHeight);

            exec("cd ". $this->getDirName() . " & convert " . $this->getFullFileName() . " -crop " . $pieceWidth . "x" . $pieceHeight . "+" . $imgPieceSizeWidth * $i . "+" . $imgPieceSizeHeight * $j . " " . $i . "_" . $j . ".jpg");

        
    




    $img->cutImgIntoPieces(500, 500, 'C:/xampp/htdocs/');

【问题讨论】:

你应该把你的php代码。也许用 GD 种植会更快?你是在最终服务器上运行它吗? ImageMagick crop huge image的可能重复 可能存在其他方法 您是否尝试过链接中的方法? 【参考方案1】:

在命令行(在中型 iMac 上)我可以使用以下命令在 2 分 44 秒内实现您想要做的事情:

convert -crop 500x500 image.jpg tile%04d.jpg

这样你只读取一次图像并且只执行一次convert,它会为你计算出所有的瓦片,每个瓦片都是500x500,名称类似于tile1799.jpg

更新

为了更快地获得它,我这样做了。首先,将图像平铺成 4 个象限,分别称为 quad00.jpgquad01.jpgquad02.jpgquad03.jpg,如下所示 - 注意最后的 @ 指定了平铺的数量而不是大小:

convert -crop 2x2@ image.jpg quad%02d.jpg

现在我可以运行 4 个并行进程来将象限拆分为 500x500 的图块并保持所有 CPU 内核繁忙:

#!/bin/bash
convert -crop 500x500 quad00.jpg tile0-%04d.jpg &
convert -crop 500x500 quad01.jpg tile1-%04d.jpg &
convert -crop 500x500 quad02.jpg tile2-%04d.jpg &
convert -crop 500x500 quad03.jpg tile3-%04d.jpg &
wait

将原始图像拆分为 4 个象限需要 52 秒,然后将所有四个象限并行拆分为 500x500 块又需要 7 秒,总时间为 59 秒。

在回答您关于初始 4 个象限大小不均等的进一步问题时,您可以随意按照自己的喜好进行最初的四个象限 - 您比我更了解您的图像!事实上,根据您的 CPU,您可能最好使用 8 个初始图块,或者 2 个。无论如何,您需要进行试验。为了做到这一点,您可以像这样计算图像的大小(宽度和高度),然后进行一些数学运算来决定您想要如何处理初始象限、半边或其他:

# Get width
w=$(identify -format %w image.jpg)

echo $w
30000

# Get height
h=$(identify -format %h image.jpg)

echo $h
20000

【讨论】:

太慢了,我需要大约一秒钟才能得到结果 太搞笑了!我将时间减少了 900 倍,您的评论是它太慢了。 嗯,我知道您每 59 秒裁剪了所有 2800 个零件? 我测试它真的很好!也许我可以在第一步中得到四个部分“quad00,quad01,quad02,quad03”得到不等于这个例子的四个部分:如果有 21000px x 20 000px(第一部分得到 10 000px x 10 000px,第二部分得到 11 000px x 10 000px ) 我已经添加了一些关于如何做到这一点的提示。请再看看。

以上是关于图像中的PHP图片部分(CROP)的主要内容,如果未能解决你的问题,请参考以下文章

添加图像、替换、裁剪、删除部分

图像缩放、滚动视图、裁剪

Dart/Flutter 替代 PHP 调整裁剪图像大小?

裁剪图像并使用 ffmpeg 截取左侧部分

ImageMagick - 沿内部非透明对象边框分割透明度图像

Python裁剪图片(Crop an Image)