应用滤镜后如何下载图像? [复制]
Posted
技术标签:
【中文标题】应用滤镜后如何下载图像? [复制]【英文标题】:How do I download an image after applying filter on it? [duplicate] 【发布时间】:2021-12-04 20:08:46 【问题描述】:我正在使用照片编辑器,我想在用户对原始图像进行必要的更改后下载编辑后的图像。所以过滤值取决于用户,不是恒定的
更改工作正常,但是当我单击下载时,我得到的是原始版本而不是修改后的版本。有人对我如何进一步进行有任何想法吗? (P.S. 我搜索了整个 Stack Overflow 并尝试在我的代码中实现每个解决方案,但没有任何效果)
const canvas = document.getElementById("img");
const ctx = canvas.getContext("2d");
let img = new Image();
let fileName = "";
const downloadBtn = document.getElementById("download-btn");
const uploadFile = document.getElementById("upload-file");
const revertBtn = document.getElementById("revert-btn");
// Upload File
uploadFile.addEventListener("change", () =>
// Get File
const file = document.getElementById("upload-file").files[0];
// Init FileReader API
const reader = new FileReader();
// Check for file
if (file)
// Set file name
fileName = file.name;
// Read data as URL
reader.readAsDataURL(file);
// Add image to canvas
reader.addEventListener(
"load",
() =>
// Create image
img = new Image();
// Set image src
img.src = reader.result;
// On image load add to canvas
img.onload = function()
canvas.width = img.width;
canvas.height = img.height;
ctx.drawImage(img, 0, 0, img.width, img.height);
canvas.removeAttribute("data-caman-id");
;
,
false
);
);
// Download Event
downloadBtn.addEventListener("click", () =>
// Get ext
const fileExtension = fileName.slice(-4);
// Init new filename
let newFilename;
// Check image type
if (fileExtension === ".jpg" || fileExtension === ".png")
// new filename
newFilename = fileName.substring(0, fileName.length - 4) + "-edited.jpg";
// Call download
download(canvas, newFilename);
);
// Download
function download(canvas, filename)
// Init event
let e;
// Create link
const link = document.createElement("a");
// Set props
link.download = filename;
link.href = canvas.toDataURL("image/jpeg", 0.8);
// New mouse event
e = new MouseEvent("click");
// Dispatch event
link.dispatchEvent(e);
const options =
sepia: 0,
rotation: 0,
scale: 1,
;
function setSepia(e)
options.sepia = e.value;
document.getElementById('Amount').innerhtml = "(" + e.value + ")";
redraw();
let rotation = 0;
function RotateImg()
rotation += 90;
if (rotation == 360)
rotation = 0;
options.rotation = rotation;
redraw();
let scale = 1
function flipping()
scale -= 2
if (scale <= -2)
scale = 1;
options.scale = scale;
redraw();
let invertVal = 0
function invert()
invertVal += 100
if (invertVal > 100)
invertVal = 0
options.invertVal = invertVal;
redraw();
function redraw()
document.getElementById("img").style["webkitFilter"] = "sepia(" + options.sepia + ")
grayscale(" + options.grayscale + ") brightness(" + options.brightness + ") contrast(" +
options.contrast + ") opacity(" + options.opacity + ") invert(" + options.invertVal + ")"; document.querySelector("img").style.transform = `rotate($options.rotationdeg)
scaleX($options.scale)`;
<!-- class="custom-file-label" -->
<p><input type="file" id="upload-file">upload</input>
</p>
<p><label for="upload-file">Upload Image</label></p>
<p><canvas id="img"></canvas></p>
<button id="download-btn" class="btn btn-primary btn-block">Download</button>
<div class="sidenav">
<label for="filter-select">FILTER AND ADJUST</label>
<div class="slider">
<p style="color: aliceblue;">Sepia</p>
<input id="sepia" type="range" oninput="setSepia(this);" value="0" step="0.1" min="0" max="1"><span id="Amount" style="color: white;"> (0)</span><br /><br>
</div>
<label onclick="RotateImg()">ROTATE</label>
<label onclick="flipping()">FLIP</label>
</div>
【问题讨论】:
【参考方案1】:乔·卡维亚,
欢迎来到***!我试图运行你的代码但没有成功,但我知道你想要做什么,所以我开始构建一个图像编辑器,它应该可以解决你的许多疑问
我会在此留下一些注意事项:
我从这个nice editor sample的主干开始 我将原始文件保存在<img>
中,并将编辑后的图像放入<canvas>
previewFiles()方法用于设置两张图片,最多来自this page
按照您的正确做法以及 this question 的建议,您需要 <canvas>
才能保存应用了 CSS 过滤器的图像
我将应用多个过滤器,如great example 所示
然后我们将在另一个great example之后下载编辑后的图像[实际上是<canvas>
]
注意:当我尝试在 *** 编辑器中运行示例时 [下面这个] 我无法真正下载图像,但如果您在 JSFiddle 中运行相同的代码,它就可以工作 注意:我在 Chrome 上对其进行了测试,但如果这可能是一个问题,我会更深入地检查浏览器兼容性
// checking activity on filters values
// calling the apply_filter method as soon as a slider is moved or set into a position
$(document).ready(function()
$(".range").change(apply_filter).mousemove(apply_filter);
);
// global variable
const original_image = document.getElementById('original_image_preview');
// setting canva size and return its context to drawing functions
function initializeCanva()
// creating the additional canva to show the filters action
const canvas = document.getElementById('edited_image_canva');
const ctx = canvas.getContext('2d');
// assigning it the same size of the original image preview
canvas.width = original_image.width;
canvas.height = original_image.height;
return ctx;
// loading and previewing the files
function previewFiles()
const preview = document.querySelector('img');
const file = document.querySelector('input[type=file]').files[0];
const reader = new FileReader();
// the load event is fired only when a file has been read successfully, unlike loadend - because we need a success to get started
reader.addEventListener("load", function()
// returning the file content
preview.src = reader.result;
// creating the canva to reflect the edits immediately after the original image has been loaded
const ctx = initializeCanva();
// drawing the original image on the canva
ctx.drawImage(original_image, 0, 0, original_image.width, original_image.height);
, false);
// reading the contents of the specified [image] file
// when the read operation is successfully finished, the load event is triggered - at that time, the result attribute contains the data as a data: URL representing the file's data as a base64 encoded string
if (file)
reader.readAsDataURL(file);
// called everytime a slider is hovered or moved around
// atm needed also to show the canva after the original image has been loaded
function apply_filter()
// getting the filter values from the sliders elements
var grayscale_val = $("#grayscale").val();
//console.log(grayscale_val + "%");
var blur_val = $("#blur").val();
var exposure_val = $("#exposure").val();
var sepia_val = $("#sepia").val();
var opacity_val = $("#opacity").val();
// getting the context where to apply the changes
const ctx = initializeCanva();
// creating the filter from sliders values
ctx.filter = 'grayscale(' + grayscale_val + '%) blur(' + blur_val + 'px) brightness(' + exposure_val + '%) sepia(' + sepia_val + '%) opacity(' + opacity_val + '%)';
// console.log(ctx.filter);
// applying the filter on the original image
ctx.drawImage(original_image, 0, 0, original_image.width, original_image.height);
// triggered by clicking on the download button
function download()
//console.log("asking for download");
// keeping the same image quality
var data = edited_image_canva.toDataURL("image/png", 1);
// create temporary link
var tmpLink = document.createElement('a');
tmpLink.download = 'edited_image.png'; // set the name of the download file
tmpLink.href = data;
// temporarily add link to body and initiate the download
document.body.appendChild(tmpLink);
tmpLink.click();
document.body.removeChild(tmpLink);
body
text-align: center;
width: 100%;
margin: 0 auto;
padding: 0px;
font-family: Helvetica, Sans-Serif;
background-color: #E6E6E6;
#wrapper
text-align: center;
margin: 0 auto;
padding: 0px;
width: 995px;
#edit_controls
background-color: #A4A4A4;
float: left;
width: 500px;
margin-left: 248px;
#edit_controls li
list-style-type: none;
display: inline-block;
padding: 0px;
margin: 10px;
color: white;
#images_div img
width: 80%;
padding: 20px;
#images_div canvas
border: 3px solid #d3d3d3;
button
margin: 20px;
<html>
<head>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>
<body>
<div id="wrapper">
<!-- filters area -->
<div id="edit_controls">
<li>GrayScale<br><input id="grayscale" class="range" type="range" min="0" max="100" value="0"></li>
<li>Blur<br><input id="blur" class="range" type="range" min="0" max="10" value="0"></li>
<li>Exposure<br><input id="exposure" class="range" type="range" min="0" max="200" value="100"></li>
<li>Sepia<br><input id="sepia" class="range" type="range" min="0" max="100" value="0"></li>
<li>Opacity<br><input id="opacity" class="range" type="range" min="0" max="100" value="100"></li>
</div>
<!-- images area -->
<div id="images_div">
<!-- accepting only image files -->
<input type="file" accept="image/*" onchange="previewFiles()" style="margin-top: 20px"><br>
<img src="" id="original_image_preview" >
<br />Edited Image<br /><br />
<canvas id="edited_image_canva">
Your browser does not support the HTML5 canvas tag
</canvas>
<br />
<button onclick="download()">Download</button>
</div>
</div>
</body>
</html>
【讨论】:
以上是关于应用滤镜后如何下载图像? [复制]的主要内容,如果未能解决你的问题,请参考以下文章