This project is a script executed locally. Business personnel will put the finished large image materials on Google Drive, and then a Google Drive app will be installed on the machine where the project is located. The purpose is to synchronize the files and materials on Google Drive to the local folder (how to synchronize the files and materials please search by yourself).

I used the Laravel framework, wrote it in the Conslole command line, and periodically executed the script. You can also put it online, connect to Google Drive’s Webhook (I didn’t try it), and automatically trigger the task based on the notification

The project needs to install a third-party Image processing package, and I used the package Intervention\Image to install Composer

In the code

<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Intervention\Image\ImageManagerStatic as Image;

class CutImage extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'cut-image';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = '自动裁剪google drive里的最新修改的图片并上传到Google storage';

    const FILE_PATH = "/home/vagrant/cao";
    const FILE_PATH_TEMP = "/home/vagrant/cao-temp";

    const MID_H = 1024;
    const MID_NAME = 'mid-';
    const SM_H = 512;
    const SM_NAME = 'small-';
    const ICON_H = 128;
    const ICON_NAME = 'icon-';

    const STORAGE_FOLDER = 'wox-materials';
    const STORAGE_BUCKET = 'gs://storage-custom.dollarhoo-test.me/';

    public function handle()
    {
        $fileTemp = escapeshellarg(self::FILE_PATH_TEMP); // 对命令行参数进行安全转义
        $originFile = self::FILE_PATH;
        try {
            //按修改时间过滤文件并且复制到临时文件夹
            $this->filterMoveImageToTemp($originFile);
            //获取临时文件夹里的图片进行裁剪上传才做
            $file = self::FILE_PATH_TEMP;
            $imagePathLists = $this->formatImagePathMap($this->getImageList($file));
        } catch (\Exception $e) {
            echo "++++++++++++++++++++++【发生错误】+++++++++++++++++++++\n";
            echo "错误信息:" . $e->getMessage() . "\n";
            echo "错误文件:" . $e->getFile() . "\n";
            echo "错误行:" . $e->getLine() . "\n";
            echo "+++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
            $imagePathLists = [];
            //删除临时文件夹
            $shell = `rm -rf $fileTemp`;
            echo $shell;
            //todo:钉钉报警
        }
        $picNum = 1;
        $all = count($imagePathLists);
        echo "总共【{$all}】张图片\n";
        sleep(1);
        echo "开始处理第一张图\n";
        foreach ($imagePathLists as $imagePath) {
            try {
                $imageName = array_reverse(explode("/", $imagePath))[0];
                //先上传原图
                $this->moveImageToStorage($imagePath);
                echo "*******************【正在处理$imagePath 】*******************\n";
                //开始裁剪
                $img = Image::make($imagePath);
                $originW = $img->getWidth();
                $originH = $img->getHeight();
                //等比例计算
                $midW = self::MID_H / $originH * $originW;
                $smW = self::SM_H / $originH * $originW;
                $iconW = self::ICON_H / $originH * $originW;
                //mid image
                $img->resize($midW, self::MID_H);
                $mageResizeName = self::MID_NAME . $imageName;
                $midImagePath = str_replace($imageName, $mageResizeName, $imagePath);
                $img->save($midImagePath);
                //google storage sdk ,同步处理好的图片到google storage
                $this->moveImageToStorage($midImagePath);
                echo "*******************【正在处理$midImagePath 】*******************\n";
                //small image
                $img->resize($smW, self::SM_H);
                $mageResizeName = self::SM_NAME . $imageName;
                $smallImagePath = str_replace($imageName, $mageResizeName, $imagePath);
                $img->save($smallImagePath);
                //google storage sdk ,同步处理好的图片到google storage
                $this->moveImageToStorage($smallImagePath);
                echo "*******************【正在处理 $smallImagePath 】*******************\n";
                //icon image
                $img->resize($iconW, self::ICON_H);
                $mageResizeName = self::ICON_NAME . $imageName;
                $iconImagePath = str_replace($imageName, $mageResizeName, $imagePath);
                $img->save($iconImagePath);
                //google storage sdk ,同步处理好的图片到google storage
                $this->moveImageToStorage($iconImagePath);
                echo "*******************【正在处理 $iconImagePath 】*******************\n";
                echo "===================================================================\n";
                $picNum++;
                if ($picNum <= $all) {
                    echo "开始处理第{$picNum}张图\n";
                }
            } catch (\Exception $e) {
                echo "++++++++++++++++++++++【发生错误】+++++++++++++++++++++\n";
                echo "错误信息:" . $e->getMessage() . "\n";
                echo "错误文件:" . $e->getFile() . "\n";
                echo "错误行:" . $e->getLine() . "\n";
                echo "+++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
                continue;
                //todo:钉钉报警
            }
        }
        //删除临时文件夹
        $shell = `rm -rf $fileTemp`;
        echo $shell;
        echo "+++++++++++++++【所有图处理完毕!】++++++++++++++++++++\n";
    }

    /**
     * 上传临时文件夹里的文件到Google storage
     * @param string $tempImagePath 临时文件夹里的图片位置
     */
    public function moveImageToStorage(string $tempImagePath)
    {
        $storagePath = escapeshellarg(self::STORAGE_BUCKET . self::STORAGE_FOLDER . str_replace(self::FILE_PATH_TEMP, '', $tempImagePath));
        $tempImagePath = escapeshellarg($tempImagePath);
        $shell = `/home/vagrant/google-cloud-sdk/bin/gsutil cp -r $tempImagePath $storagePath`;
        echo $shell;
    }


    /**遍历临时文件夹获取所有图片树状图
     * @param string $pathName
     * @return array
     */
    public function getImageList(string $pathName): array
    {
        //将结果保存在result变量中
        $result = array();
        $temp = array();
        //判断传入的变量是否是目录
        if (!is_dir($pathName) || !is_readable($pathName)) {
            return [];
        }
        //取出目录中的文件和子目录名,使用scandir函数
        $allFiles = scandir($pathName);
        //遍历他们
        foreach ($allFiles as $fileName) {
            //判断是否是.和..因为这两个东西神马也不是。。。
            if (in_array($fileName, array('.', '..'))) {
                continue;
            }
            //路径加文件名
            $fullName = $pathName . '/' . $fileName;
            //如果是目录的话就继续遍历这个目录
            if (is_dir($fullName)) {
                //将这个目录中的文件信息存入到数组中
                $result[$fullName . '/'] = $this->getImageList($fullName);
            } else {
                //如果是文件就先存入临时变量
                $temp[] = $fileName;
            }
        }
        //取出文件
        if ($temp) {
            foreach ($temp as $f) {
                $result[] = $f;
            }
        }
        return $result;
    }

    /**
     * 遍历原始文件夹,并且按照修改时间过滤文件,并且复制到临时文件夹
     * @param string $originFile
     */
    public function filterMoveImageToTemp(string $originFile)
    {
        //判断传入的变量是否是目录
        if (!(!is_dir($originFile) || !is_readable($originFile))) {
            //取出目录中的文件和子目录名,使用scandir函数
            $allFiles = scandir($originFile);
            //遍历他们
            foreach ($allFiles as $fileName) {
                //判断是否是.和..因为这两个东西神马也不是。。。
                if (in_array($fileName, array('.', '..'))) {
                    continue;
                }
                //路径加文件名
                $fullName = $originFile . '/' . $fileName;
                //如果是目录的话就继续遍历这个目录
                if (is_dir($fullName)) {
                    //将这个目录中的文件信息存入到数组中
                    $this->filterMoveImageToTemp($fullName);
                } else {
                    $tempPathName = str_replace(self::FILE_PATH, self::FILE_PATH_TEMP, $originFile);
                    //创建临时文件夹
                    $this->mkdirs($tempPathName);
                    $shell = `find $originFile -mtime -5 -type f | xargs -i cp {} $tempPathName`;
                    echo $shell;
                }
            }
        }
    }


    /**扁平化数组
     * @param $arr
     * @return array
     */
    public function flatten($arr): array
    {
        $result = [];
        global $a;
        foreach ($arr as $k => $v) {
            if (is_array($v)) {
                $a = $k;
                $result = array_merge($result, $this->flatten($v));
            } else if (is_numeric($k)) {
                $result[$a][] = $v;
            } else {

                $result[$k] = $v;
            }
        }
        return $result;
    }

    /**
     * 整理获取到的树状文件夹图片列表成一维数组
     * @param array $imagePathLists
     * @return array
     */
    public function formatImagePathMap(array $imagePathLists): array
    {
        $imagePathLists = $this->flatten($imagePathLists);
        $imageList = [];
        foreach ($imagePathLists as $path => $imageNameLists) {
            foreach ($imageNameLists as $imageName)
                $imageList[] = $path . $imageName;
        }
        return $imageList;
    }

    /**
     * 判断文件夹是否存在,不存在就创建
     * @param $dir
     * @param int $mode
     * @return bool
     */
    public function mkdirs($dir, int $mode = 0777): bool
    {
        if (is_dir($dir) || @mkdir($dir, $mode))
            return TRUE;
        if (!$this->mkdirs(dirname($dir), $mode))
            return FALSE;
        return @mkdir($dir, $mode);
    }
}
Copy the code