使用 PHP 将图像中的一种颜色替换为另一种颜色

2024-01-07

是的,我知道 stackoverflow 上有相关的问题,但它们并不完全符合我的需要。我正在尝试用另一种颜色替换图像的颜色。在下面的代码中,我将 (255,0,255) 替换为 (0,192,239)。下面的代码可以工作,但不能完美地替换粉色(255,0,255)颜色上的新颜色,一些小点或粉色边框仍然保留,如您在输出图像中看到的那样。

我怎样才能得到它的完美解决方案?

<?php
$filename = 'img/Mascots_Aviators_General-copy.png'; 
$im = imagecreatefrompng($filename);
$out = imagecreatetruecolor(imagesx($im), imagesy($im));
$transColor = imagecolorallocatealpha($out, 254, 254, 254, 127);
imagefill($out, 0, 0, $transColor);

for ($x = 0; $x < imagesx($im); $x++) {
    for ($y = 0; $y < imagesy($im); $y++) {
        $pixel = imagecolorat($im, $x, $y);

        $red = ($pixel >> 16) & 0xFF;
        $green = ($pixel >> 8) & 0xFF;
        $blue = $pixel & 0xFF;
        $alpha = ($pixel & 0x7F000000) >> 24;

        if ($red == 255 && $green == 0 && $blue == 255) {
            $red = 0;
            $green=192;
            $blue =239;
        }

        if ($alpha == 127) {
            imagesetpixel($out, $x, $y, $transColor);
        }
        else {
            imagesetpixel($out, $x, $y, imagecolorallocatealpha($out, $red, $green, $blue, $alpha));
        }
    }
} 
imagecolortransparent($out, $transColor);
imagesavealpha($out, TRUE); 
header('Content-type: image/png');
imagepng($out);

EDIT 2 :您可能需要优化某些内容并进行更改hueAbsoluteError以满足您的需求,但色调是启蒙和更清晰的图像质量的方法(函数取自https://gist.github.com/brandonheyer/5254516 https://gist.github.com/brandonheyer/5254516):

<?php
function RGBtoHSL( $r, $g, $b ) {
    $r /= 255;
    $g /= 255;
    $b /= 255;
    $max = max( $r, $g, $b );
    $min = min( $r, $g, $b );
    $l = ( $max + $min ) / 2;
    $d = $max - $min;
    if( $d == 0 ){
        $h = $s = 0;
    } else {
        $s = $d / ( 1 - abs( 2 * $l - 1 ) );
        switch( $max ){
            case $r:
                $h = 60 * fmod( ( ( $g - $b ) / $d ), 6 );
                if ($b > $g) {
                    $h += 360;
                }
                break;
            case $g:
                $h = 60 * ( ( $b - $r ) / $d + 2 );
                break;
            case $b:
                $h = 60 * ( ( $r - $g ) / $d + 4 );
                break;
        }
    }
    return array( round( $h, 2 ), round( $s, 2 ), round( $l, 2 ) );
}

function HSLtoRGB( $h, $s, $l ){
    $c = ( 1 - abs( 2 * $l - 1 ) ) * $s;
    $x = $c * ( 1 - abs( fmod( ( $h / 60 ), 2 ) - 1 ) );
    $m = $l - ( $c / 2 );
    if ( $h < 60 ) {
        $r = $c;
        $g = $x;
        $b = 0;
    } else if ( $h < 120 ) {
        $r = $x;
        $g = $c;
        $b = 0;
    } else if ( $h < 180 ) {
        $r = 0;
        $g = $c;
        $b = $x;
    } else if ( $h < 240 ) {
        $r = 0;
        $g = $x;
        $b = $c;
    } else if ( $h < 300 ) {
        $r = $x;
        $g = 0;
        $b = $c;
    } else {
        $r = $c;
        $g = 0;
        $b = $x;
    }
    $r = ( $r + $m ) * 255;
    $g = ( $g + $m ) * 255;
    $b = ( $b + $m  ) * 255;
    return array( floor( $r ), floor( $g ), floor( $b ) );
}

/* ---------------CHANGE THESE------------------- */
$colorToReplace = RGBtoHSL(255, 0, 255);
$hueAbsoluteError = 0.4;
$replacementColor = RGBtoHSL(0, 192, 239);
/* ---------------------------------------------- */

$filename = 'img/Mascots_Aviators_General-copy.png';
$im = imagecreatefrompng($filename);
$out = imagecreatetruecolor(imagesx($im), imagesy($im));
$transColor = imagecolorallocatealpha($out, 254, 254, 254, 127);
imagefill($out, 0, 0, $transColor);

for ($x = 0; $x < imagesx($im); $x++) {
    for ($y = 0; $y < imagesy($im); $y++) {
        $pixel = imagecolorat($im, $x, $y);

        $red = ($pixel >> 16) & 0xFF;
        $green = ($pixel >> 8) & 0xFF;
        $blue = $pixel & 0xFF;
        $alpha = ($pixel & 0x7F000000) >> 24;

        $colorHSL = RGBtoHSL($red, $green, $blue);

        if ((($colorHSL[0]  >= $colorToReplace[0] - $hueAbsoluteError) && ($colorToReplace[0] + $hueAbsoluteError) >= $colorHSL[0])){
            $color = HSLtoRGB($replacementColor[0], $replacementColor[1], $colorHSL[2]);
            $red = $color[0];
            $green= $color[1];
            $blue = $color[2];
        }

        if ($alpha == 127) {
            imagesetpixel($out, $x, $y, $transColor);
        }
        else {
            imagesetpixel($out, $x, $y, imagecolorallocatealpha($out, $red, $green, $blue, $alpha));
        }
    }
}
imagecolortransparent($out, $transColor);
imagesavealpha($out, TRUE);
header('Content-type: image/png');
imagepng($out);

EDIT :更好的解决方案 - 确定颜色是否需要更换(使用此方法)。确定替换颜色的色调(我不知道这是否是正确的术语,我的意思是亮度和黑暗)。将其涂抹到替换颜色上,赋予其阴影或 AA 的感觉。


因此,正如我在评论中所说,您需要确定这种颜色是否真的很平(深色、浅色等)。最简单的解决方案是对特定颜色通道应用绝对误差方法。可能有(肯定有)更好的通用方法,但我希望这可以:

$color = [255, 0, 255];
$colorAbsoluteError = [150, 0, 150];
$replacementColor = [0, 192, 239];
$filename = 'img/Mascots_Aviators_General-copy.png';
$im = imagecreatefrompng($filename);
$out = imagecreatetruecolor(imagesx($im), imagesy($im));
$transColor = imagecolorallocatealpha($out, 254, 254, 254, 127);
imagefill($out, 0, 0, $transColor);

for ($x = 0; $x < imagesx($im); $x++) {
    for ($y = 0; $y < imagesy($im); $y++) {
        $pixel = imagecolorat($im, $x, $y);

        $red = ($pixel >> 16) & 0xFF;
        $green = ($pixel >> 8) & 0xFF;
        $blue = $pixel & 0xFF;
        $alpha = ($pixel & 0x7F000000) >> 24;

        if ((($red  >= $color[0] - $colorAbsoluteError[0]) && ($color[0] + $colorAbsoluteError[0]) >= $red) &&
            (($green  >= $color[1] - $colorAbsoluteError[1]) && ($color[1] + $colorAbsoluteError[1]) >= $green) &&
            (($blue  >= $color[2] - $colorAbsoluteError[2]) && ($color[2] + $colorAbsoluteError[2]) >= $blue)){
            $red = $replacementColor[0];
            $green= $replacementColor[1];
            $blue = $replacementColor[2];
        }

        if ($alpha == 127) {
            imagesetpixel($out, $x, $y, $transColor);
        }
        else {
            imagesetpixel($out, $x, $y, imagecolorallocatealpha($out, $red, $green, $blue, $alpha));
        }
    }
}
imagecolortransparent($out, $transColor);
imagesavealpha($out, TRUE);
header('Content-type: image/png');
imagepng($out);
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 PHP 将图像中的一种颜色替换为另一种颜色 的相关文章

  • 一次播种多行 laravel 5

    我目前正在尝试为我的用户表播种 如果我像这样尝试 2 行 就会失败 如果我只使用单个数组而不是 users 数组内的 2 个数组来创建一些假数据 那么效果很好 我做错了什么 正确的方法是什么 class UserTableSeeder ex
  • 内部 while 循环不工作

    这是我项目网页上的代码片段 这里我想显示用户选择的类别 然后想显示属于该类别的主题 在那里 用户可以拥有多个类别 这没有问题 我可以在第一个 while 循环中打印所有这些类别 问题是当我尝试打印主题时 结果只显示一行 但每个类别中有更多主
  • ini_set 'session.gc_maxlifetime' 为 1 天

    If I do ini set session gc maxlifetime 86400 这是否意味着用户可以将浏览器留在同一页面 非活动状态 最多 1 天 而不必担心会话被垃圾收集并被注销 如果服务器配置不支持此功能会发生什么 它会给我一
  • 为什么 Composer 降级了我的包?

    php composer phar update这样做了 删除了 2 3 0 软件包并安装了整个 2 2 5 Zend Framework php composer phar update Loading composer reposito
  • 如何使用 PHPExcel 库从 Excel 获取日期

    我正在尝试使用 PHPExcel 从 Excel 获取日期 但我没有得到日期 我得到的字符串值不是 1970 以来的秒数 我尝试过的代码是 InvDate trim excel gt getActiveSheet gt getCell B
  • 无法显示 Laravel 欢迎页面

    我的服务器位于 DigitalOcean 云上 我正在使用 Ubuntu 和 Apache Web 服务器 我的家用计算机运行的是 Windows 7 我使用 putty 作为终端 遵循所有指示https laracasts com ser
  • PHP 如何再次传输 mp3 流

    我正在尝试从 http 的无线电流 MP3 获取数据 并希望以 https 的形式将其流式传输 这是我尝试过的
  • 在 PHP 中使用 Curl 将获取字段附加到 URL

    我可以使用 Curl 执行服务器端和客户端重定向 但无法通过 get 请求将 GET 字段附加到 URL 这是我的代码 post curl init curl setopt post CURLOPT URL url curl setopt
  • 替换多余的空格

    我需要从应用程序中的玩家用户名中删除多余的空格 字母之间不止一次空格 并将其替换为单个空格 我不介意用户有一个空格 但我需要删除彼此相邻的多个空格 目前我是这样实现的 replace array array fill array array
  • octobercms 任务调度不起作用

    我正在使用基于 Laravel 的 OctoberCMS 我没有 SSH 访问我的服务器的权限 每天我需要删除一些注册后 24 小时内未激活帐户的用户 所以我正在考虑使用任务调度 如 cronjobs 根据 10 月 CMSdocs htt
  • 如何在 Codeigniter 中将变量从一个控制器传递到另一个控制器

    我刚刚开始学习 Code Igniter 我想知道如何将变量从一个控制器 first cont php 传递到另一个控制器 second cont php 任何帮助 将不胜感激 提前致谢 这将取决于具体情况 如果您想将数据保留一段时间 那么
  • Pinterest 身份验证 url 返回 404 错误?

    我正在测试 pinterest apihttp pinterest com developers api http pinterest com developers api 在上面的身份验证部分的网址上 它说我必须将用户重定向到 pinte
  • php 注意到 $GLOBALS['HTTP_SERVER_VARS']['HTTP_HOST'] 中未定义索引 http_host

    突然 在最近的 php 版本更新后 我从 php 收到了此通知 它在多个地方使用 特别是我的 htmlMimeMail 类 代码是 mail gt setSMTPParams mail xxxx xxx 26 GLOBALS HTTP SE
  • 如何使用具有比较标准的 findBy 方法

    我需要使用使用比较标准 不仅仅是精确标准 的 神奇查找器 findBy 方法 换句话说 我需要做这样的事情 result purchases repository gt findBy array prize gt gt 200 这样我就可以
  • 在 PHP 中将对象作为参数传递[关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 无法使用模式 r: fopen(): AWS Elastic Beanstalk 打开

    错误 无法使用模式 r fopen 打开 文件名不能为空当我尝试上传较大的文件 超过 5MB 时 我不断收到此错误 我已将 PHP 应用程序上传到 AWS Elastic Beanstalk 并将文件上传到 AWS S3 我的代码中甚至没有
  • 使用 jquery 和 php 测试表单输入是否为 1 或 2 位整数

    我有一个表单 其中有五个字段全部设置为 maxlength 2 基本上 我希望唯一可以输入的值是一位或两位整数 因为在将值存储在数据库中之前对这些字段执行计算 是否有任何 jquery 不允许用户输入不是整数的值 另外 用 jquery 和
  • MySQL 的 TEXT 类型的 Oracle 等效项

    Oracle 是否有与 MySQL 等效的列类型TEXT type 如果不是 那么通常如何存储较大的文本块 BLOB varchar 32767 如果重要的话 它是通过 PHP 访问 Oracle 10 历史背景是非常受欢迎的 Oracle
  • 如何使用 Mockery 在第 N 次调用模拟方法时抛出异常

    我需要测试我编写的某些代码多次调用另一个类上的方法时的行为 其中一次调用将导致抛出异常 我在用Mockery http docs mockery io模拟可能引发异常的类 因此 就我而言 该方法将被调用三次 我需要它在第二次抛出异常 这是我
  • 正则表达式 - 匹配单词缩写

    我正在考虑提供以下正则表达式作为答案这个问题 https stackoverflow com questions 2110010 how to find wordpresss installed on domain or server pr

随机推荐

  • runMain 中的 sbt 非法动态引用

    我正在尝试运行代码生成器 并向其传递文件名以写入输出 resourceGenerators in proj Compile Def task val file resourceManaged in proj Compile value sw
  • 查明 Objective-C 类是否重写了方法 [重复]

    这个问题在这里已经有答案了 如何在运行时确定一个类是否重写了其超类的方法 例如 我想知道一个类是否有它自己的实现isEqual or hash 而不是依赖超类 您只需要获取方法列表 然后查找您想要的方法 import
  • 在 Flash 模式下寻找超出缓冲线的视频

    网络服务器模块ngx http mp4 module or mod h264 streaming允许 Flash 客户端使用 start 参数寻找超出下载缓冲区线的视频 例如 http server com path to video mp
  • 实体,处理大量记录(> 3500 万条)

    我们有一组相当大的相关表 每个表有超过 3500 万条相关记录 我需要创建几个 WCF 方法 它们使用一些参数 数据范围 类型代码等 查询数据库并返回相关结果集 从 10 到 10 000 条记录 该公司采用 EF 4 0 进行标准化 但对
  • 从 MS Access 2007 中删除 autoexec 宏

    我在 MS Access 2007 中创建了一个 autoexec 宏 但找不到它 我知道它在那里 因为它正在运行 但我找不到它来删除或修改 我可以看到我创建的其他宏 但没有看到自动执行宏 有人可以指出我正确的方向以找到它所在的位置 干杯
  • 如何获取最后滚动视图位置,scrollview

    我正在使用表格布局 其中有 100 个项目使其可滚动我在 ScrollView 中使用 Tablelayout 但我必须检测用户是否已滚动到最后一行 如果用户滚动到最后一个视图 则会向用户显示一条 Toast 消息 但是如何知道用户已滚动到
  • 配置 Silex 防火墙使用 api 密钥的正确方法

    我一直致力于制作一个接受 api 密钥的 api 并按照以下说明进行操作http symfony com doc current cookbook security api key authentication html http symf
  • 当前在 github 和 npmjs.org 上“退役”项目的最佳实践?

    我是 github 和 npm 上一个公共项目的维护者 当我创建该项目时 它比可用的替代方案更好地解决了我的特定需求 然而 社区已经赶上了并超越了我的解决方案 我什至不再使用我创建的工具 而且我对维护它不感兴趣 我为此更新了自述文件 但我仍
  • SQL Server 2005 报告服务 - 优点和缺点

    我正在使用 ASP NET 2 0 VS 2008 和 SQL Server 2005 开发一个 Web 应用程序 我想使用 SSRS 2005 来生成我需要为此 Web 应用程序构建的各种报告 我想说服团队 我们应该采用 SSRS 作为我
  • java.util.zip.ZipException:与 firebase 重复条目

    我正在使用 firebase 构建一个应用程序 但出现重复类错误 我已经检查了所有依赖项 但我无法弄清楚我在哪里有两个版本的 firebase 库 错误 任务 app transformClassesWithJarMergingForDeb
  • JavaScript 元组中的变量赋值

    在 Python 2 和 Python 3 等其他语言中 您可以定义元组变量并将值分配给元组变量 然后像这样检索它们的值 tuple Bob 24 name age tuple print name name evaluates to Bo
  • 如何自定义角度谷歌图表图例信息

    I have google chart line chart need to customize legend with some extra information Please refer this http plnkr co edit
  • MinGW C++ 使用向量退出值 127

    我在 C 中使用向量时遇到问题 我正在 Windows NetBeans 上使用 MinGW 以下代码 include
  • C使用malloc分配内存[重复]

    这个问题在这里已经有答案了 我不太明白 char string string malloc 1 if string NULL printf Couldn t able to allocate requested memory n else
  • 错误:用户“myuser”的密码验证失败

    如果我在 etc postgresql 9 4 main pg hba conf 中有一条记录特别信任我的特定用户 TYPE DATABASE USER ADDRESS METHOD local all myuser trust 因为我在
  • 你能在 Java 中运行真正的 ping 吗?

    过去几周我做了相当多的研究 试图创建一个连接诊断工具 我不想只是检查连接是否可用 而是诊断是否存在抖动 数据包丢失等 到目前为止 Java 似乎不支持真正的 ICMP 请求 并且有一些解决方法 但没有一个能够实现我想要做的事情 有谁知道是否
  • 基本的 javascript 所见即所得编辑器

    我可以获得有关如何使用文本区域制作所见即所得编辑器的解释吗 我需要它做的就是解析基本的 html 标签 如粗体 斜体 下划线等 它不需要任何插入它的按钮 我只想在解析的文本区域标签内有一个默认文本html Example
  • 我怎样才能有启用/禁用按钮附近的条目的功能?

    import tkinter as tk class App tk Frame def init self super init self pack self buttons self entries for n row in range
  • WiX 包含与片段

    WiX 包括 wxi文件 和 WiX 片段 wxs文件 每个的用例是什么 Which should被使用 为什么 文件扩展名只是为了方便 文件的内容才是真正重要的 这种区别使得管理实际安装 wxs 文件 和创建安装所需的属性 wxi 文件
  • 使用 PHP 将图像中的一种颜色替换为另一种颜色

    是的 我知道 stackoverflow 上有相关的问题 但它们并不完全符合我的需要 我正在尝试用另一种颜色替换图像的颜色 在下面的代码中 我将 255 0 255 替换为 0 192 239 下面的代码可以工作 但不能完美地替换粉色 25