In diesem ersten Tutorial unserer CamanJS-Bildbearbeitungsreihe bearbeiten wir Bilder nur mit integrierten Filtern. Dies beschränkt uns auf einige grundlegende Effekte wie Helligkeit, Kontrast und 18 weitere komplexere Filter wie Vintage, Sonnenaufgang usw. Sie sind alle einfach anzuwenden, wir haben jedoch nicht die vollständige Kontrolle über die einzelnen Pixel des Bildes, das wir bearbeiten möchten.
In diesem zweiten Tutorial haben wir etwas über Ebenen und Mischmodi gelernt, die uns mehr Kontrolle über das Bild geben, das wir bearbeiten. Sie können der Leinwand beispielsweise eine neue Ebene hinzufügen, diese mit einer Farbe oder einem Bild füllen, sie dann auf der übergeordneten Ebene platzieren und einen Füllmodus anwenden. Allerdings haben wir noch keinen eigenen Filter erstellt und die Mischmodi, die wir anwenden können, beschränken sich auf die bereits von CamanJS bereitgestellten.
Der Zweck dieses Tutorials besteht darin, Ihnen beizubringen, wie Sie Ihre eigenen Mischmodi und Filter erstellen. Wir gehen auch auf einige in der Bibliothek vorhandene Fehler ein und zeigen, wie Sie diese beheben können, wenn Sie CamanJS in Ihren eigenen Projekten verwenden.
Standardmäßig bietet CamanJS zehn Mischmodi. Sie sind „Normal“, „Multiplizieren“, „Maskieren“, „Addieren“, „Differenzieren“, „Addieren“, „Ausschließen“, „Weiches Licht“, „Aufhellen“ und „Abdunkeln“. In der Bibliothek können Sie auch Ihre eigenen Mischmodi registrieren. Auf diese Weise können Sie steuern, wie die entsprechenden Pixel der aktuellen Ebene und der übergeordneten Ebene miteinander vermischt werden, um das Endergebnis zu erzielen.
Sie können Caman.Blender.register("blend_mode", callback);
创建新的混合模式。此处,blend_mode
是您要用来识别您正在创建的混合模式的名称。回调函数接受两个参数,其中包含当前图层上不同像素和父图层上相应像素的 RGB 值。该函数返回一个对象,其中包含 rgb
den Endwert des Kanals verwenden.
Hier ist ein Beispiel für einen benutzerdefinierten Mischmodus, der den Wert jedes Kanals des Pixels auf 255 setzt, wenn der Kanalwert des entsprechenden Pixels in der übergeordneten Ebene 128 überschreitet. Wenn der Wert niedriger als 128 ist, ist der endgültige Kanalwert der Wert des übergeordneten Kanals minus dem Wert des aktuellen Layer-Kanals. Der Name dieses Mischmodus ist 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 }; });
Lassen Sie uns auf ähnliche Weise einen weiteren Mischmodus erstellen. Wenn diesmal der Kanalwert des entsprechenden Pixels in der übergeordneten Ebene größer als 128 ist, wird der endgültige Kanalwert auf 0 gesetzt. Wenn der Kanalwert der übergeordneten Ebene weniger als 128 beträgt, ist das Endergebnis die Addition der Kanalwerte der aktuellen Ebene und der übergeordneten Ebene für das spezifische Pixel. Dieser Mischmodus wurde minrgb
genannt.
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 }; });
Sie sollten zum Üben versuchen, Ihre eigenen Mischmodi zu erstellen.
In CamanJS gibt es zwei Haupttypen von Filtern. Sie können das gesamte Bild Pixel für Pixel bearbeiten oder Faltungskerne verwenden, um das Bild zu ändern. Der Faltungskern ist eine Matrix, die die Farbe eines Pixels anhand der ihn umgebenden Pixel bestimmt. In diesem Abschnitt konzentrieren wir uns auf pixelbasierte Filter. Kernel-Operationen werden im nächsten Abschnitt behandelt.
Pixelbasierte Filter geben den RGB-Kanalwerten Pixel für Pixel zu. Der endgültige RGB-Wert dieses bestimmten Pixels wird nicht durch umgebende Pixel beeinflusst. Sie können die Caman.Filter.register("filter_name", callback);
创建自己的过滤器。您创建的任何过滤器都必须调用 process()
-Methode verwenden. Diese Methode akzeptiert den Filternamen und die Rückruffunktion als Parameter.
Der folgende Codeausschnitt zeigt Ihnen, wie Sie einen pixelbasierten Filter erstellen, der ein Bild in Graustufen umwandelt. Dazu wird die Lumineszenz jedes Pixels berechnet und anschließend die Werte der einzelnen Kanäle gleich der berechneten Lumineszenz gesetzt.
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; });
Auf ähnliche Weise können Sie Schwellenwertfilter erstellen. Dieses Mal werden wir Benutzern erlauben, einen Schwellenwert zu überschreiten. Wenn die Helligkeit eines bestimmten Pixels höher ist als der vom Benutzer angegebene Grenzwert, wird das Pixel weiß. Wenn die Helligkeit eines bestimmten Pixels unter einen vom Benutzer festgelegten Grenzwert fällt, wird dieses Pixel schwarz.
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; });
Als Übung sollten Sie versuchen, einen eigenen pixelbasierten Filter zu erstellen, um beispielsweise den Wert eines bestimmten Kanals für alle Pixel zu erhöhen.
CamanJS ermöglicht Ihnen außerdem, die Farbe absolut und relativ positionierter Pixel festzulegen, anstatt die Farbe des aktuellen Pixels zu manipulieren. Leider ist dieses Verhalten etwas fehlerhaft, sodass wir einige Methoden überschreiben müssen. Wenn Sie sich den Quellcode dieser Bibliothek ansehen, werden Sie getPixel()
和 putPixel()
等方法调用了 方法<code class="inline">this
上的 和 上的 和 bemerken. Diese Methoden werden jedoch nicht im Prototyp, sondern in der Klasse selbst definiert.
Ein weiteres Problem mit dieser Bibliothek ist putPixelRelative()
方法在两个不同的地方使用变量名称 nowLoc
而不是 newLoc
. Sie können beide Probleme beheben, indem Sie Ihrem Skript den folgenden Code hinzufügen.
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 网站上的指南,以了解我可能错过的任何内容。我还建议您阅读该库的源代码,以了解有关图像处理的更多信息。这也将帮助您发现库中的任何其他错误。
Das obige ist der detaillierte Inhalt vonEntwicklung eines benutzerdefinierten Bildeditors mit CamanJS: Erweiterte Filteroptionen und Mischmodi. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!