如何裁剪多边形外的区域?

2023-12-02

我想使 PHP 中预定义多边形之外的任何内容变得透明。假设您有头部的形状,那么图像的其他任何内容都应该被分箱。 预先非常感谢! 为了让自己清楚,这是我一直在编写的一些代码:

$dat = dirname(__FILE__)."/foto_".time().".png";
$img = imagecreatefrompng("foto.png");
$points = array(93,36,147,1,255,-5,294,37,332,114,327,189,315,249,303,291,290,327,260,360,205,404,165,407,131,376,86,325,62,236,61,155,66,96,77,57,87,45);
$schwarz = ImageColorAllocate ($img, 0, 0, 0);
imagefilledpolygon($img, $points, count($points)/2, $schwarz);
imagepng($img, $dat);

原图可以找到here和结果here。一切except黑色区域应该被丢弃。


我知道有点晚了,但我在网上查找了此问题的解决方案,但找不到一体化的解决方案。我发现的许多帖子都涉及按像素编辑图像,但我不太喜欢这样做。将多个站点的多个样本拼凑在一起后,我得出以下结论:

调整裁剪多边形图像的大小()

function resizeCropPolygonImage($source, $dest = null, 
        $newWidth = null, $newHeight = null, $startX = 0, $startY = 0, 
        $points = array(), $numCoords = 2) {

    // Added in $numCoords in case we want to do 3D image processing in the future
    // (currently we do not process anything other than 2D coordinates)
    $points = array(100,115, 124,65, 192,65, 216,115, 192,165, 124,165);
    $numPoints = count($points) / $numCoords;

    // If there are not enough points to draw a polygon, then we can't perform any actions
    if ($numPoints < 3) {
        return;
    }

    // Get the original image's info
    list($width, $height, $file_type) = getimagesize($source);

    /******* Here I am using a custom function to resize the image  *********
     ******* keeping the aspect ratio.                              *********
     ******* You'll have to add in your own re-sizing logic         *********
    // Resize the source (using dummy vars because we don't want our
    // start x & y to be overwritten)
    scaleDimensions($width, $height, $newWidth, $newHeight, $dummyX = null, $dummyY = null);
    For simplicity sake, I'll just set the width and height to the new width and height
    *************************************************************************/
    $width = $newWidth;
    $height = $newHeight;

    switch ($file_type) {
    case 1:
        $srcImage = imagecreatefromgif($source);
        if (function_exists(ImageGIF)) {
            $imgType = "gif";
        } else {
            $imgType = "jpeg";
        }
        break;
    case 2:
        $srcImage = imagecreatefromjpeg($source);
        $imgType = "jpeg";
        break;
    case 3:
        $srcImage = imagecreatefrompng($source);
        $imgType = "png";
        break;
    default:
        return;
    }

    // Setup the merge image from the source image with scaling
    $mergeImage = ImageCreateTrueColor($width, $height);
    imagecopyresampled($mergeImage, $srcImage, 0, 0, 0, 0, $width, $height, imagesx($srcImage), imagesy($srcImage));

    /******** This is probably the part that you're most interested in *******/
    // Create the image we will use for the mask of the polygon shape and
    // fill it with an uncommon color
    $maskPolygon = imagecreatetruecolor($width, $height);
    $borderColor = imagecolorallocate($maskPolygon, 1, 254, 255);
    imagefill($maskPolygon, 0, 0, $borderColor);

    // Add the transparent polygon mask
    $transparency = imagecolortransparent($maskPolygon, imagecolorallocate($maskPolygon, 255, 1, 254));
    imagesavealpha($maskPolygon, true);
    imagefilledpolygon($maskPolygon, $points, $numPoints, $transparency);

    // Apply the mask
    imagesavealpha($mergeImage, true);
    imagecopymerge($mergeImage, $maskPolygon, 0, 0, 0, 0, $width, $height, 100);

    /******* Here I am using a custom function to get the outer     *********
     ******* perimeter of the polygon. I'll add this one in below   ********/
    // Crop down to just the polygon area
    $polygonPerimeter = getPolygonCropCorners($points, $numCoords);
    $polygonX = $polygonPerimeter[0]['min'];
    $polygonY = $polygonPerimeter[1]['min'];
    $polygonWidth = $polygonPerimeter[0]['max'] - $polygonPerimeter[0]['min'];
    $polygonHeight = $polygonPerimeter[1]['max'] - $polygonPerimeter[1]['min'];

    // Create the final image
    $destImage = ImageCreateTrueColor($polygonWidth, $polygonHeight);
    imagesavealpha($destImage, true);
    imagealphablending($destImage, true);
    imagecopy($destImage, $mergeImage, 
            0, 0, 
            $polygonX, $polygonY,
            $polygonWidth, $polygonHeight);

    // Make the the border transparent (we're assuming there's a 2px buffer on all sides)
    $borderRGB = imagecolorsforindex($destImage, $borderColor);
    $borderTransparency = imagecolorallocatealpha($destImage, $borderRGB['red'],
            $borderRGB['green'], $borderRGB['blue'], 127);
    imagesavealpha($destImage, true);
    imagealphablending($destImage, true);
    imagefill($destImage, 0, 0, $borderTransparency);

    if (!$dest) {
        // If no dest was given, then return to browser
        header('Content-Type: image/png');
        imagepng($destImage);
    } else {
        // Output image will always be png
        $dest .= '.png';

        // Save to destination
        imagepng($destImage, $dest);
    }

    // Destroy remaining images
    imagedestroy($maskPolygon);
    imagedestroy($srcImage);
    imagedestroy($destImage);

    // Only return a value if we were given a destination file
    if ($dest) {
        return $dest;
    }
}

getPolygonCropCorners()

function getPolygonCropCorners($points, $numCoords) {
    $perimeter = array();

    for ( $i = 0; $i < count($points); $i++ ) {
        $axisIndex = $i % $numCoords;

        if (count($perimeter) < $axisIndex) {
            $perimeter[] = array();
        }

        $min = isset($perimeter[$axisIndex]['min']) ? $perimeter[$axisIndex]['min'] : $points[$i];
        $max = isset($perimeter[$axisIndex]['max']) ? $perimeter[$axisIndex]['max'] : $points[$i];

        // Adding an extra pixel of buffer
        $perimeter[$axisIndex]['min'] = min($min, $points[$i] - 2);
        $perimeter[$axisIndex]['max'] = max($max, $points[$i] + 2);
    }

    return $perimeter;
}

使用这个功能,我可以转动这个图像

Large giraffes

进入这个

Small giraffes

它可能并不完全完整,但我认为这绝对是一个很好的起点。


EDIT

  • 09/19/2014 - 增加了边框的透明度
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何裁剪多边形外的区域? 的相关文章

  • 学说“没有命名的协会”

    将我添加到无法找出其学说映射出了什么问题的人列表中 我正在模拟国际象棋Game与一对多Halfmoves 有任何想法吗 DDL create table game game id int primary key create table h
  • Laravel 集合 .each() + array_push

    需要有关 Laravel 上 each 方法内的 array push 的帮助 我无法在此代码上获取容器数组 imagesData array collect data images gt each function v k use ima
  • 如何以 Magento 方式实现库存过滤器?

    在我的 magento 网站上可以看到缺货的产品 我想要在分层导航中添加一个自定义过滤器 其中显示 排除缺货 当客户单击它时 应该隐藏缺货产品 默认情况下 我在 系统 gt 配置 gt 目录 gt 库存 下启用显示 显示缺货产品 即我希望客
  • SQL 大表中的随机行(使用 where 子句)

    我有一个网站 人们可以在其中对汽车进行投票 向用户展示 4 辆汽车 他 她可以投票选出他们最喜欢的汽车 桌子cars有重要的列 car id int 10 not auto increment so has gaps views int 7
  • header() 错误未在 php 中显示

    我写了一个PHP程序 我用session start and header 函数 我知道在向客户端发送任何内容之前应该使用此函数 没关系 但是为了测试 我向客户端发送了一条测试消息echo test 在使用 header 之前 但我没有收到
  • 更新重复密钥上的复合密钥 [重复]

    这个问题在这里已经有答案了 我需要更新新行 如果两者都满足 date dat and empId who 作为复合键 但如果其中之一或两者不同 则插入 sql INSERT INTO history SET endtimestamp now
  • 使用 PhpStorm 删除 CakePHP 中的插件后出现“成员有私人访问错误”

    从我的 CakePHP 框架中删除插件以及与其关联的所有代码行后 我在以下位置收到错误getInitializer的功能autoload static php in my vendor gt composer folder public s
  • 使用 PHP/COM/ADSI/LDAP 更改 AD 密码

    我已经被这个问题困扰了好几天了 我尝试了各种解决方案均无济于事 请帮忙 Problem 我们有两个域控制器 它们不属于我们的管理范围 我们能够通过端口 389 上的 LDAP 进行连接 但无法通过端口 636 安全连接 我们正在开发一个系统
  • 如何验证使用 php 上传的文件不包含可执行二进制文件?

    使用简单的 Firefox 插件 黑客可以更改他们想要上传的任何文件的 MIME 类型 绕过文件类型检查器 然后 黑客可以使用 GIMP 等程序将 php 脚本嵌入到图像 音频或任何其他文件的二进制数据中 我该如何检查并防止这种情况发生 您
  • 使用 HTTP-Basic 身份验证发出 HTTP GET 请求

    我需要为我正在开发的 Flash Player 项目构建一个代理 我只需要使用 HTTP Basic 身份验证向另一个 URL 发出 HTTP GET 请求 并提供来自 PHP 的响应 就好像 PHP 文件是原始源一样 我怎样才能做到这一点
  • TCPDF/PHP 和字体:大写数字(血统数字?旧样式?)

    我得到了一种特殊的字体 上面有这样的数字 例如 正如您在 3 上看到的 一些数字下降到基线以下 我想要实现的是 这些数字不会低于该线 并且看起来像这样 在 Word 中 可以在相同字体的字符设置中轻松设置 如何在 TCPDF 中呈现数字 我
  • Facebook Graph API v3.1 开发人员访问令牌权限限制

    如您所知 Facebook 将其 API 升级到了 V3 1 现在正在慢慢地淘汰旧的 API 和应用程序 因此我们必须迁移到新的 API 他们做出了一些艰难的决定 这对垃圾邮件网站来说是好事 但对开发人员来说也很难 提醒 Graph API
  • PHP 相等变量

    我想知道是否有任何方法可以检查大量变量是否相等 如果我只有几个变量 我可以这样做 if a b a c b c 但是 如果我有 20 个变量 则需要一些时间来编写所有组合 还有其他方法吗 if count array unique arra
  • 访客客户检查 Woocommerce 订单账单电子邮件时可享受首单折扣

    通过对照正在处理和已完成的订单检查来宾客户的电子邮件地址 如果电子邮件没有订单 我想给来宾 首单折扣 如果这能在客人输入电子邮件时发生 那就太好了 我想我已经成功制作了折扣代码 现在我请求帮助合并这两个代码 使其一切正常 这是折扣代码 ad
  • 在 PHP 中将十进制/双精度/浮点值与 PDO 绑定的最佳方法是什么?

    看来类常量只涵盖PDO PARAM BOOL PDO PARAM INT and PDO PARAM STR用于绑定 您只是将十进制 浮点 双精度值绑定为字符串还是有更好的方法来处理它们 MySQLi 允许使用 d 类型表示 double
  • 如何在 Laravel 代码中使用 Artisan 命令?

    如何在我的 php caode Ex 中使用 Artisan 命令行 php artisan version to 您可以从控制器调用 Artisan 命令 如下所示 calling of migrate install Artisan c
  • 从数据库 MYSQL 和 Codeigniter 获取信息

    如果你们需要其他信息 上一个问题就在这里 从数据库中获取信息 https stackoverflow com questions 13336744 fetching information from the database 另一个更新 尽
  • 高效插入和更新时检查唯一性

    我的员工表中有 2 列 每列值必须是唯一的 staff code staff name staff id staff code staff name 1 MGT Management 2 IT IT staff 当向表中插入或更新项目时 我
  • 如何使用 PHP 获取列中的所有值?

    我一直在到处寻找这个问题 但仍然找不到解决方案 如何从 mySQL 列中获取所有值并将它们存储在数组中 例如 表名称 客户 列名称 ID 名称 行数 5 我想获取此表中所有 5 个名称的数组 我该如何去做呢 我正在使用 PHP 我试图 SE
  • 如何显示 PHP 对象

    我有这样的代码 dataRecord1 client gt GetRecord token table filter echo pre print r dataRecord1 echo pre foreach dataRecord1 gt

随机推荐

  • 如何使用自定义ant规则正则表达式更改属性文件中的属性

    在我的 Android 项目中 我在 project properties 文件中设置了以下属性 proguard config proguard cfg 我需要一个自定义宏来以某种方式设置和取消设置此属性 如何使用宏和正则表达式设置取消设
  • C# 引用和指针有什么区别?

    我不太明白 C 引用和指针之间的区别 它们都指向记忆中的某个地方 不是吗 我能弄清楚的唯一区别是指针不那么聪明 不能指向堆上的任何东西 可以免于垃圾回收 并且只能引用结构或基类型 我问这个问题的原因之一是 人们认为人们需要很好地理解指针 我
  • 在curl中发送json文件并使用plumber在R中接收它

    我需要发送一个包含多个值的 json 文件并使用水管工在 R 中接收它 我尝试过这个 但它似乎不起作用 library rjson install packages rjson get predict post predict functi
  • Jquery 实时复制另一个文本框值

    我想获取另一个文本框的值并将其实时输入到另一个文本框中 如何检测 TEXT 3 是否已更改 如果 TEXT 3 值更改 则必须将其输入到 TEXT 4 为了您的方便 这里是代码和演示 HTML
  • 使用PHP查询MDB文件,并返回JSON

    我有一个 Microsoft Access 数据库 我正在尝试使用 PHP 查询该表 并输出有效的 JSON 我有一个 MSSQL 数据库的等效代码 我正在尝试让我的代码做同样的事情 但只是针对 Access 数据库 这是MSSQL代码 m
  • Angular2 嵌套 formGroups - formArrays 和模板绑定

    问题是这样的 我有一个带有嵌套表单组的复杂表单 这是它的 简化 结构 gt MyForm formGroup gt Whatever01 formControl input gt Whatever02 formControl input g
  • Bundler如何卸载冲突的依赖项

    我正在尝试执行vagrant plugin install vagrant vbguest在我的 Mac 上 ProductName Mac OS X ProductVersion 10 12 6 BuildVersion 16G29 但之
  • 分页时出现 SQL 错误

    大家好 我们有一个完美工作的关系控制器网页 index admin 但在添加分页后 它全部崩溃了 想出 SQLSTATE 42S22 Column not found 1054 Unknown column Relationship sen
  • 我想在 Nuxt.js 中的 Vuex 中使用 window.localStorage

    我开发 nuxt js 应用程序 重点是登录和注销 我们将开发 JWT 系统的登录 您必须保持 vuex 登录状态 但是 当我刷新页面时 vuex 被初始化 我读过 gitvuex 持久状态 但很难理解如何初始化和设置它 在 nuxt js
  • WPF 使用数据绑定显示格式化的多行文本

    我需要使用 WPF 数据绑定显示以下内容 值发生变化 标题必须是粗体 信息行是普通文本 如果给定标头的信息不存在 我想折叠该部分 包括标头 我更喜欢所有数据 标题和信息项 都位于一个格式化字符串中 该字符串可以在我想要的位置换行 Heade
  • 我们应该支持哪些 Xamarin ABI

    目前 我认为我们的 Xamarin Android 应用程序 PCL 非常庞大 即使在发布模式下也是如此 我怀疑这是由于支持的架构造成的 目前我们已将它们全部选中 有谁知道我们是否必须选择所有这些 我们也根本不使用 Android NDK
  • jQuery - .always() 回调触发得太快

    我正在开发一个客户端 JS 应用程序 该应用程序应该读取 CSV 文件 每行进行一些 API 调用 然后将结果写回 CSV 我所关注的部分是如何编排请求并在所有完成后触发一个函数 这是我到目前为止所拥有的 var requests loop
  • 使用“on”和“by”从两个 data.table 计算新变量

    我怎么不能用by当通过两个计算新变量时data tables合并后 示例数据集 library data table set seed 1 Example datasets dt1 lt data table id 1 10 var rno
  • 安卓中的OBB是什么

    我不知道如何使用OBB 有演示吗 我不知道它的优点 在android2 3以下的设备上使用会抛出异常吗 Detail 我读过一些有关它的文章 但我仍然不太了解 人们使用它似乎只是因为应用程序大小限制为 50mb 使用它可以将其扩大到4GB
  • 如何使用 scipy odeint 求解这个微分方程?

    我正在尝试使用 scipy odeint 求解以下微分方程 但没有取得太大成功 import numpy as np from scipy misc import derivative from scipy integrate import
  • 根据 Python str.format() 文档,什么是有效键

    我是 Python 新手 刚刚阅读了 Python 文档中的以下部分6 1 3 格式化字符串语法 Because arg name is not quote delimited it is not possible to specify a
  • 无法从 mainBundle 中删除文件

    我在从主包中删除文件时遇到问题 当我从 XCODE 4 2 中的支持文件中手动删除它们时 当我运行我的应用程序时它们仍然出现 我已经使用 显示包内容 打开了应用程序文件 并从那里手动删除了它们 当我运行应用程序时它们仍然显示 我已从模拟器和
  • 如何检查docker容器内是否正在运行进程?

    更新1 我有一个shell 它会更改某些功能中的TCP内核参数 但现在我需要使这个shell在Docker容器中运行 这意味着 shell需要知道它正在容器内运行并停止配置内核 现在我不知道如何实现这一点 这是内容 proc self cg
  • 如何将名称附加到 R 中输出数据帧的“列名称”?

    我知道我可以使用更改列的名称 colnames x lt c Column1 Column 2 Column 3 Column 4 如果我有 A lt Apple B lt Banana 我应该怎么做才能使输出数据帧的名称具有这样的名称 C
  • 如何裁剪多边形外的区域?

    我想使 PHP 中预定义多边形之外的任何内容变得透明 假设您有头部的形状 那么图像的其他任何内容都应该被分箱 预先非常感谢 为了让自己清楚 这是我一直在编写的一些代码 dat dirname FILE foto time png img i