目录
创建新的混合模式
创建新的基于像素的过滤器
创建新的基于内核操作的过滤器
最终想法
首页 CMS教程 &#&按 使用 CamanJS 开发自定义图像编辑器:扩展滤镜选项和混合模式

使用 CamanJS 开发自定义图像编辑器:扩展滤镜选项和混合模式

Aug 28, 2023 am 10:05 AM

使用 CamanJS 开发自定义图像编辑器:扩展滤镜选项和混合模式

在我们的 CamanJS 图像编辑器系列的第一个教程中,我们仅使用内置过滤器来编辑图像。这限制了我们一些基本效果,如亮度、对比度和 18 个其他更复杂的滤镜,如 Vintage、Sunrise 等。它们都很容易应用,但我们无法完全控制我们想要的图像的各个像素进行编辑。

在第二个教程中,我们了解了图层和混合模式,这使我们能够更好地控制正在编辑的图像。例如,您可以在画布上添加一个新图层,用颜色或图像填充它,然后将其放置在父图层上并应用混合模式。然而,我们仍然没有创建自己的过滤器,并且我们可以应用的混合模式仅限于 CamanJS 已经提供的模式。

本教程的目的是教您如何创建自己的混合模式和滤镜。我们还将解决库中存在的一些错误,以及在您自己的项目中使用 CamanJS 时如何修补它们。

创建新的混合模式

默认情况下,CamanJS 提供十种混合模式。它们是正常、相乘、屏蔽、叠加、差值、加法、排除、柔光、变亮和变暗。该库还允许您注册自己的混合模式。这样,您就可以控制当前图层和父图层的相应像素如何混合在一起以产生最终结果。

您可以使用 Caman.Blender.register("blend_mode", callback); 创建新的混合模式。此处,blend_mode 是您要用来识别您正在创建的混合模式的名称。回调函数接受两个参数,其中包含当前图层上不同像素和父图层上相应像素的 RGB 值。该函数返回一个对象,其中包含 rgb 通道的最终值。

下面是自定义混合模式的示例,如果父图层中相应像素的通道值超过 128,则该像素的各个通道的值设置为 255。如果该值低于 128,则最终通道值是父通道值减去当前层通道值的结果。该混合模式的名称是 maxrgb

Caman.Blender.register("maxrgb", function(rgbaLayer, rgbaParent) {
    return {
        r: rgbaParent.r > 128 ? 255 : rgbaParent.r - rgbaLayer.r,
        g: rgbaParent.g > 128 ? 255 : rgbaParent.g - rgbaLayer.g,
        b: rgbaParent.b > 128 ? 255: rgbaParent.b - rgbaLayer.b
    };
});
登录后复制

让我们以类似的方式创建另一个混合模式。这次,如果父层对应像素的通道值大于128,则最终的通道值将被设置为0。如果父层的通道值小于128,则最终结果将是相加特定像素的当前图层和父图层的通道值。此混合模式已命名为 minrgb

Caman.Blender.register("minrgb", function(rgbaLayer, rgbaParent) {
    return {
        r: rgbaParent.r < 128 ? rgbaParent.r + rgbaLayer.r : 0,
        g: rgbaParent.g < 128 ? rgbaParent.g + rgbaLayer.r : 0,
        b: rgbaParent.b < 128 ? rgbaParent.r + rgbaLayer.r : 0
    };
});
登录后复制

您应该尝试创建自己的混合模式进行练习。

创建新的基于像素的过滤器

CamanJS 中有两大类过滤器。您可以一次对整个图像进行一个像素操作,也可以使用卷积核修改图像。卷积核是一个矩阵,它根据某个像素周围的像素来确定该像素的颜色。在本节中,我们将重点关注基于像素的滤波器。内核操作将在下一节中介绍。

基于像素的滤镜一次给出一个像素的 RGB 通道值。该特定像素的最终 RGB 值不受周围像素的影响。您可以使用 Caman.Filter.register("filter_name", callback); 创建自己的过滤器。您创建的任何过滤器都必须调用 process() 方法。此方法接受过滤器名称和回调函数作为参数。

以下代码片段向您展示如何创建基于像素的过滤器,将图像变成灰度。这是通过计算每个像素的发光,然后将各个通道的值设置为等于计算的发光来完成的。

Caman.Filter.register("grayscale", function () {
    this.process("grayscale", function (rgba) {
        var lumin = (0.2126 * rgba.r) + (0.7152 * rgba.g) + (0.0722 * rgba.b);
        rgba.r = lumin;
        rgba.g = lumin;
        rgba.b = lumin;
    });
    return this;
});
登录后复制

您可以以类似的方式创建阈值过滤器。这次,我们将允许用户通过一个阈值。如果特定像素的亮度高于用户提供的限制,则该像素将变成白色。如果特定像素的亮度低于用户提供的限制,该像素将变黑。

Caman.Filter.register("threshold", function (limit) {
    this.process("threshold", function (rgba) {
        var lumin = (0.2126 * rgba.r) + (0.7152 * rgba.g) + (0.0722 * rgba.b);
        rgba.r = lumin > limit ? 255 : 0;
        rgba.g = lumin > limit ? 255 : 0;
        rgba.b = lumin > limit ? 255 : 0;
    });
    return this;
});
登录后复制

作为练习,您应该尝试创建自己的基于像素的过滤器,例如,增加所有像素上特定通道的值。

CamanJS 还允许您设置绝对和相对位置像素的颜色,而不是操纵当前像素的颜色。不幸的是,这种行为有点错误,所以我们必须重写一些方法。如果您查看该库的源代码,您会注意到 getPixel()putPixel() 等方法调用了 方法<code class="inline">this 上的 和 上的 和 。但是,这些方法不是在原型上定义的,而是在类本身上定义的。

该库的另一个问题是 putPixelRelative() 方法在两个不同的地方使用变量名称 nowLoc 而不是 newLoc 。您可以通过在脚本中添加以下代码来解决这两个问题。

Caman.Pixel.prototype.coordinatesToLocation = Caman.Pixel.coordinatesToLocation
Caman.Pixel.prototype.locationToCoordinates = Caman.Pixel.locationToCoordinates

Caman.Pixel.prototype.putPixelRelative = function (horiz, vert, rgba) {
    var newLoc;
    if (this.c == null) {
        throw "Requires a CamanJS context";
    }
    newLoc = this.loc + (this.c.dimensions.width * 4 * (vert * -1)) + (4 * horiz);
    if (newLoc > this.c.pixelData.length || newLoc < 0) {
        return;
    }
    this.c.pixelData[newLoc] = rgba.r;
    this.c.pixelData[newLoc + 1] = rgba.g;
    this.c.pixelData[newLoc + 2] = rgba.b;
    this.c.pixelData[newLoc + 3] = rgba.a;
    return true;
};
登录后复制

更正代码后,您现在应该能够创建依赖于 putPixelRelative() 的过滤器,没有任何问题。这是我创建的一个这样的过滤器。

Caman.Filter.register("erased", function (adjust) {
    this.process("erased", function (rgba) {
        if(Math.random() < 0.25) {
        rgba.putPixelRelative(2, 2, {
            r: 255,
            g: 255,
            b: 255,
            a: 255
        });
        }
    });
    return this;
});
登录后复制

此过滤器将当前像素向上两行和右侧两列的像素值随机设置为白色。这会擦除部分图像。这就是过滤器名称的由来。

创建新的基于内核操作的过滤器

正如我之前提到的,CamanJS 允许您创建自定义滤镜,其中当前像素的颜色由其周围的像素决定。基本上,这些滤镜会遍历您正在编辑的图像中的每个像素。图像中的一个像素将被其他八个像素包围。图像中这九个像素的值乘以卷积矩阵的相应条目。然后将所有这些乘积加在一起以获得像素的最终颜色值。您可以在 GIMP 文档中更详细地了解该过程。

就像基于像素的过滤器一样,您可以使用 Caman.Filter.register("filter_name", callback); 定义自己的内核操作过滤器。唯一的区别是您现在将在回调函数内调用 processKernel()

这是使用内核操作创建浮雕过滤器的示例。

Caman.Filter.register("emboss", function () {
    this.processKernel("emboss", [
        -2, -1, 0,
        -1, 1, 1,
        0, 1, 2
    ]);
});
登录后复制

以下 CodePen 演示将展示我们在本教程中创建的所有过滤器的实际操作。

最终想法

在本系列中,我几乎涵盖了 CamanJS 在基于画布的图像编辑方面提供的所有内容。您现在应该能够使用所有内置滤镜、创建新图层、在这些图层上应用混合模式以及定义您自己的混合模式和滤镜功能。

您还可以浏览 CamanJS 网站上的指南,以了解我可能错过的任何内容。我还建议您阅读该库的源代码,以了解有关图像处理的更多信息。这也将帮助您发现库中的任何其他错误。

以上是使用 CamanJS 开发自定义图像编辑器:扩展滤镜选项和混合模式的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

<🎜>:泡泡胶模拟器无穷大 - 如何获取和使用皇家钥匙
4 周前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系统,解释
4 周前 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora:巫婆树的耳语 - 如何解锁抓钩
3 周前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

热门话题

Java教程
1673
14
CakePHP 教程
1429
52
Laravel 教程
1333
25
PHP教程
1278
29
C# 教程
1257
24
如何在 WordPress 中获取登录用户信息以获得个性化结果 如何在 WordPress 中获取登录用户信息以获得个性化结果 Apr 19, 2025 pm 11:57 PM

最近,我们向您展示了如何通过允许用户将自己喜欢的帖子保存在个性化库中来为用户创建个性化体验。您可以通过在某些地方(即欢迎屏幕)使用他们的名字,将个性化结果提升到另一个水平。幸运的是,WordPress使获取登录用户的信息变得非常容易。在本文中,我们将向您展示如何检索与当前登录用户相关的信息。我们将利用get_currentuserinfo(); 功能。这可以在主题中的任何地方使用(页眉、页脚、侧边栏、页面模板等)。为了使其工作,用户必须登录。因此我们需要使用

wordpress文章列表怎么调 wordpress文章列表怎么调 Apr 20, 2025 am 10:48 AM

有四种方法可以调整 WordPress 文章列表:使用主题选项、使用插件(如 Post Types Order、WP Post List、Boxy Stuff)、使用代码(在 functions.php 文件中添加设置)或直接修改 WordPress 数据库。

如何开始WordPress博客:初学者的分步指南 如何开始WordPress博客:初学者的分步指南 Apr 17, 2025 am 08:25 AM

博客是人们在网上表达观点、意见和见解的理想平台。许多新手渴望建立自己的网站,却因担心技术障碍或成本问题而犹豫不决。然而,随着平台不断发展以满足初学者的能力和需求,现在开始变得比以往任何时候都更容易。 本文将逐步指导您如何建立一个WordPress博客,从主题选择到使用插件提升安全性和性能,助您轻松创建自己的网站。 选择博客主题和方向 在购买域名或注册主机之前,最好先确定您计划涵盖的主题。个人网站可以围绕旅行、烹饪、产品评论、音乐或任何激发您兴趣的爱好展开。专注于您真正感兴趣的领域可以鼓励持续写作

如何在父分类的存档页面上显示子分类 如何在父分类的存档页面上显示子分类 Apr 19, 2025 pm 11:54 PM

您想了解如何在父分类存档页面上显示子分类吗?在自定义分类存档页面时,您可能需要执行此操作,以使其对访问者更有用。在本文中,我们将向您展示如何在父分类存档页面上轻松显示子分类。为什么在父分类存档页面上显示子分类?通过在父分类存档页面上显示所有子分类,您可以使其不那么通用,对访问者更有用。例如,如果您运行一个关于书籍的WordPress博客,并且有一个名为“主题”的分类法,那么您可以添加“小说”、“非小说”等子分类法,以便您的读者可以

如何在 WordPress 中按帖子过期日期对帖子进行排序 如何在 WordPress 中按帖子过期日期对帖子进行排序 Apr 19, 2025 pm 11:48 PM

过去,我们分享过如何使用PostExpirator插件使WordPress中的帖子过期。好吧,在创建活动列表网站时,我们发现这个插件非常有用。我们可以轻松删除过期的活动列表。其次,多亏了这个插件,按帖子过期日期对帖子进行排序也非常容易。在本文中,我们将向您展示如何在WordPress中按帖子过期日期对帖子进行排序。更新了代码以反映插件中更改自定义字段名称的更改。感谢Tajim在评论中让我们知道。在我们的特定项目中,我们将事件作为自定义帖子类型。现在

wordpress主机怎么建站 wordpress主机怎么建站 Apr 20, 2025 am 11:12 AM

要使用 WordPress 主机建站,需要:选择一个可靠的主机提供商。购买一个域名。设置 WordPress 主机帐户。选择一个主题。添加页面和文章。安装插件。自定义您的网站。发布您的网站。

如何使用 IFTTT 自动化 WordPress 和社交媒体(及更多) 如何使用 IFTTT 自动化 WordPress 和社交媒体(及更多) Apr 18, 2025 am 11:27 AM

您是否正在寻找自动化 WordPress 网站和社交媒体帐户的方法? 通过自动化,您将能够在 Facebook、Twitter、LinkedIn、Instagram 等平台上自动分享您的 WordPress 博客文章或更新。 在本文中,我们将向您展示如何使用 IFTTT、Zapier 和 Uncanny Automator 轻松实现 WordPress 和社交媒体的自动化。 为什么要自动化 WordPress 和社交媒体? 自动化您的WordPre

wordpress怎么导入源码 wordpress怎么导入源码 Apr 20, 2025 am 11:24 AM

导入 WordPress 源码需要以下步骤:创建子主题以进行主题修改。导入源码,覆盖子主题中的文件。激活子主题,使其生效。测试更改,确保一切正常。

See all articles