不久前,我写了一些教程,描述了如何仅使用css将不同种类的滤镜和混合模式应用于图像。在您想要显示同一图像的灰度、模糊或高对比度版本的情况下,这可能非常有用。您可以使用几行 CSS 将这些效果应用于原始图像,而不是创建四个不同的图像。
在大多数情况下,使用 CSS 过滤器和混合模式效果很好。但是,CSS 不会修改图像本身的像素。换句话说,过滤器和混合模式或任何其他效果都不是永久性的。
如果有人下载应用了 CSS 过滤器的图像,他们将获得原始图像而不是修改后的版本。如果您计划为您的用户创建图像编辑器,这可能是一个重大挫折。
如果您希望图像修改是永久的并允许用户下载修改后的图像,您可以使用html5 canvas。该canvas
元素允许您做很多事情,包括绘制线条和形状、编写文本和渲染动画。
在本教程中,我们将专注于编辑加载在画布上的图像。CSS3 已经具有内置功能,可让您直接应用对比度、亮度和模糊等效果。使用html5画布时,我们将使用名为CamanJS的画布操作库来编辑图像。
该库支持开箱即用的亮度、对比度和饱和度等基本效果。这将节省时间并允许我们基于这些基本过滤器创建更复杂的过滤器。
CamanJS 基础知识
这个库的名称是基于它用于在javascript (JS) 中进行 (ca)nvas (man)ipulation 的事实。在开始使用库的不同功能之前,您必须将其包含在您的项目中。这可以通过下载库并自己托管或 直接链接到 CDN 来完成。
有两种使用库的方法。第一个选项是将data-caman
属性与图像元素一起使用。该属性可以接受不同 CamanJS 过滤器的组合作为其值。例如,如果要将图像的亮度提高 20,对比度提高 10,可以使用以下 HTML:
<img src="path/to/image.jpg" data-caman="brightness(20) contrast(10)">
同样,您可以应用其他过滤器,如饱和度、曝光、噪声、棕褐色等。除了基本过滤器,CamanJS 还允许您访问一些更复杂的过滤器。这些过滤器可以以类似的方式应用于图像。要应用sunrise
过滤器,您只需使用以下 HTML:
<img src="path/to/image.jpg" data-caman="sunrise()">
处理图像的第二个选项是调用已渲染图像Caman()
的id
画布和要应用于渲染图像的不同过滤器。
Caman('#canvas-id', function () { this.brightness(20); this.contrast(10); this.render(); });
在本系列中,我们将采用 JavaScript 方式来创建我们的图像编辑器。
实现上传和下载功能
您需要为用户提供一种上传他们想要编辑的图像的方法,以便您可以在画布上渲染它们以进行进一步操作。用户进行更改后,他们还应该能够下载编辑后的图像。在本节中,我们会将这两个功能添加到我们的图像编辑器中。
让我们从添加画布和上传/下载按钮所需的 HTML 开始:
<div class="preview-wrapper"> <canvas id="canvas"></canvas> <p class="process-message"></p> </div> <div class="editor-buttons"> <input type="file" id="upload-file" placeholder="Upload a Picture" /> <label for="upload-file">Upload a Picture</label> <button id="download-btn">Download Image</button> <br/> </div>
下面是实现基本图片上传功能的代码:
var img = new Image(); var canvas = document.getElementById('canvas'); var ctx = canvas.getContext('2d'); var fileName = ''; $("#upload-file").on("change", function(){ var file = document.queryselector('#upload-file').files[0]; var reader = new FileReader(); if (file) { fileName = file.name; reader.readAsDataURL(file); } reader.addeventListener("load", function () { img = new Image(); img.src = reader.result; img.onload = function () { canvas.width = img.width; canvas.height = img.height; ctx.drawImage(img, 0, 0, img.width, img.height); $("#canvas").removeAttr("data-caman-id"); } }, false); });
我们首先创建一些变量来存储用户选择的图像文件的名称和画布的上下文。之后,我们编写代码以在触发事件input
后 从文件中获取图像文件。change
用户选择的文件存储在 aFileList
中,我们可以使用 . 从列表中获取第一个文件.files[0]
。
一旦我们有了文件,我们就使用一个FileReader
对象来读取用户选择的文件的内容。成功读取所选文件后触发 的onload
事件。FileReader
在对象的onload
事件处理程序中 ,我们使用构造函数FileReader
创建一个HTMLImageElement
实例。Image()
然后将图像的src
属性设置为我们的 result 属性的值FileReader
。
成功加载图像后,我们将画布的宽度和高度设置为等于用户选择的图像的width
和。height
之后,我们在画布上绘制图像并从画布中移除data-caman-id
属性。
在设置画布以编辑图像时,该属性由 CamanJS 自动添加。每次用户选择新文件时,我们都需要将其删除,以避免我们正在编辑的旧图像文件与用户选择的新文件之间发生任何混淆。
除了在画布中加载图像文件外,我们还将 fileName
变量的值设置为等于用户选择的文件的名称。当我们保存编辑后的图像时,这将很有用。
用户现在可以在您的图像编辑器中上传不同的图像。一旦他们编辑了图像,他们也想下载它们。让我们编写一些代码,允许用户保存编辑后的图像文件。
$('#download-btn').on('click', function (e) { var fileExtension = fileName.slice(-4); if (fileExtension == '.jpg' || fileExtension == '.png') { var actualName = fileName.substring(0, fileName.length - 4); } download(canvas, actualName + '-edited.jpg'); }); function download(canvas, filename) { var e; var lnk = document.createElement('a'); lnk.download = filename; lnk.href = canvas.toDataURL("image/jpeg", 0.8); if (document.createEvent) { e = document.createEvent("MouseEvents"); e.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null); lnk.dispatchEvent(e); } else if (lnk.fireEvent) { lnk.fireEvent("onclick"); } }
每次为下载按钮触发事件时,我们使用jquery方法执行一段代码。 此代码从用户选择的图像文件的名称中删除文件扩展名,并将其替换为后缀。然后将此名称与对我们渲染和编辑图像的画布的引用一起传递给函数。 .on()
click
-edited.jpg
download
下载函数创建一个链接并将其download
属性设置为filename
。该href
属性包含已编辑图像的数据 URI。在设置了这两个属性的值之后,我们程序会为我们新创建的链接触发点击事件。此单击开始下载已编辑的图像。
应用内置过滤器
正如我在教程开头提到的,CamanJS 带有基本的内置过滤器。因此,您可以直接应用亮度、对比度、棕褐色、饱和度、曝光、噪点、锐化、鲜艳度和色调。一些过滤器,如亮度和对比度,可以有一个负值和一个正值。
您可以根据需要将值设置为高或低,但明智的选择是将它们保持在 -100 和 100 之间。例如,当您将亮度设置为 100 时,图像会变为白色。因此,任何高于 100 的值都会没用。同样,如果将对比度的值设置为 -100,图像将变为完全灰色。
其他滤镜(如棕褐色、噪点、锐化和模糊)仅接受正值。请记住,色调过滤器覆盖了整个 360 度圆圈,其值范围为 0 到 100。当您将色调设置为 0 或 100 时,图像看起来会完全相同。
这是为我们的图像编辑器添加按钮的 HTML:
<div class="filter-buttons"> <div class="filter-group"> <button id="brightness-dec">-</button> <span class="filter-name">Brightness</span> <button id="brightness-inc">+</button> </div> <!-- More Such Buttons --> <div class="filter-group"> <button id="gamma-dec" class="disabled">-</button> <span class="filter-name">Gamma</span> <button id="gamma-inc">+</button> </div> </div> <div class="editor-buttons"> <input type="file" id="upload-file" placeholder="Upload a Picture" /> <label for="upload-file">Upload a Picture</label> <button id="download-btn">Download Image</button> <br/> <button id="vintage-btn">Vintage</button> <!-- More Such Buttons --> <button id="lomo-btn">Lomo</button> </div>
所有的过滤器,如亮度和对比度,都有增加和减少按钮。但是,对于某些过滤器(例如噪声),减小按钮已被禁用,因为它们不能具有有意义的负值。
我们将在以下 javaScript 的帮助下根据单击的按钮应用相应的过滤器。
/* Similar Code for All Other Buttons */ $('#brightness-inc').on('click', function (e) { Caman('#canvas', img, function () { this.brightness(10).render(); }); }); $('#brightness-dec').on('click', function (e) { Caman('#canvas', img, function () { this.brightness(-10).render(); }); }); /* Similar Code for All Inbuilt Filters */ $('#nostalgia-btn').on('click', function (e) { Caman('#canvas', img, function () { this.nostalgia().render(); }); }); $('#majestic-btn').on('click', function (e) { Caman('#canvas', img, function () { this.herMajesty().render(); }); });
对于增加和减少按钮,过滤器的强度取决于其效果的缩放方式。比如亮度和对比度增加10,但是每次点击后gamma的值只增加0.1。
下面的 CodePen 演示展示了我们实际创建的 CamanJS 图像编辑器。
有些过滤器可能需要一些时间才能看到它们的最终结果。在这种情况下,用户可能会认为过滤器不起作用。我们将使用事件来让读者了解过滤器的进度。所有这些都将在下一个教程中讨论。
最后的想法
第一个教程旨在教您如何创建具有基本图像上传和下载功能的图像编辑器,用户可以使用它来编辑图像。我们使用了噪点、对比度和亮度等基本过滤器,以及库中内置的一些更复杂的效果,如 Vintage 和 Nostalgia。