英文:
Cropping a masked clipped image
问题
我已创建了一个SVG遮罩,允许显示图像的特定部分。以下是相关的代码:
<!-- language: lang-css -->
.svg-defs {
position: absolute;
width: 0;
height: 0;
}
.container {
position: relative;
top: 20px;
left: 50px;
}
.background::before {
content: '';
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
background: url(https://fastly.picsum.photos/id/553/200/300.jpg?hmac=-A3VLW_dBmwUaXOe7bHhCt-lnmROrPFyTLslwNHVH1A) no-repeat;
opacity: .1;
}
img {
clip-path: url(#clipper);
}
<!-- language: lang-html -->
<svg class='svg-defs'>
<defs>
<clipPath id='clipper'>
<rect x="30" y="120" width="100" height="100" />
</clipPath>
</defs>
</svg>
<div class='container'>
<div class='background'>
<img src="https://fastly.picsum.photos/id/553/200/300.jpg?hmac=-A3VLW_dBmwUaXOe7bHhCt-lnmROrPFyTLslwNHVH1A" />
</div>
</div>
请注意,我在CSS中使用.background::before
仅用于美观地显示图像作为淡化的背景。
至于您的要求,您想要编写JavaScript代码,当执行时(可能通过单击按钮触发),它将裁剪图像仅为剪切的部分(或上面图像中的亮部分),并且您应该能够最终将其保存到文件中(换句话说,您只想保存图像的亮部分作为新图像,或者至少能够在单独的img
标签中显示它)。
英文:
I have created an SVG mask that allows showing only a certain part of an image. Here is the code for that:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-css -->
.svg-defs {
position: absolute;
width: 0;
height: 0;
}
.container {
position: relative;
top: 20px;
left: 50px;
}
.background::before {
content: '';
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
background: url(https://fastly.picsum.photos/id/553/200/300.jpg?hmac=-A3VLW_dBmwUaXOe7bHhCt-lnmROrPFyTLslwNHVH1A) no-repeat;
opacity: .1;
}
img {
clip-path: url(#clipper);
}
<!-- language: lang-html -->
<svg class='svg-defs'>
<defs>
<clipPath id='clipper'>
<rect x="30" y="120" width="100" height="100" />
</clipPath>
</defs>
</svg>
<div class='container'>
<div class='background'>
<img src="https://fastly.picsum.photos/id/553/200/300.jpg?hmac=-A3VLW_dBmwUaXOe7bHhCt-lnmROrPFyTLslwNHVH1A" />
</div>
</div>
<!-- end snippet -->
Please note that I am using .background::before
in CSS for the sole purpose of displaying the image as a faded background, for aesthetics.
Now, so far, everything is great. What I want to do is write JavaScript code, which when executed (maybe triggered via a click of a button), it will crop the image to the clipped part only (or the bright part in the image above), and which I should be able to save into a file eventually (in other words, I only want to save the bright section of the image as a new image, or at least be able to display it in a separate img
tag)
Thank you.
答案1
得分: 1
After a lot of investigation, and reading the article suggested by @BretDonald, I came up with the following solution. I am putting it here for the greater good.
const cropSize = {
width: 100,
height: 100
}
// Function to crop the image
const crop = () => {
const canvas = document.querySelector("#cropped");
const ctx = canvas.getContext('2d');
ctx.drawImage(img, 70, 140, cropSize.width, cropSize.height, 0, 0, cropSize.width, cropSize.height);
}
const img = new Image();
img.src = 'https://fastly.picsum.photos/id/290/200/300.jpg?hmac=kjRyFwJ6i5kuROjzxcs6QbXbBr8EptbH5AuVxtMxhQ0';
img.onload = (() => {
const canvas = document.querySelector("#image");
const ctx = canvas.getContext('2d');
ctx.drawImage(img, 70, 140, cropSize.width, cropSize.height, 70, 140, cropSize.width, cropSize.height);
});
#main {
display: flex;
flex-direction: column;
align-items: center;
box-sizing: border-box;
width: 500px;
height: 400px;
}
#container {
flex-grow: 1;
box-sizing: border-box;
border: 1px solid black;
background-color: lightgray;
position: relative;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
#image-and-background {
position: relative;
width: 200px;
height: 300px;
background-color: white;
}
#background::before {
content: '';
background: url('https://fastly.picsum.photos/id/290/200/300.jpg?hmac=kjRyFwJ6i5kuROjzxcs6QbXbBr8EptbH5AuVxtMxhQ0') no-repeat;
opacity: 0.3;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
<div id='main'>
<div id='container'>
<div id='image-and-background'>
<div id='background'>
<canvas id='image' width='200' height='300'></canvas>
</div>
</div>
</div>
</div>
<div>
<p>Click on the "Crop" button below for a cropped image</p>
<canvas id='cropped' width='100' height='100'></canvas>
<div id='buttons'>
<input type="button" id="button1" onclick="crop()" value="Crop" />
</div>
</div>
英文:
After a lot of investigation, and reading the article suggested by @BretDonald, I came up with the following solution. I am putting it here for the greater good.
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
const cropSize = {
width: 100,
height: 100
}
// Function to crop the image
const crop = () => {
const canvas = document.querySelector("#cropped");
const ctx = canvas.getContext('2d');
ctx.drawImage(img, 70, 140, cropSize.width, cropSize.height, 0, 0, cropSize.width, cropSize.height);
}
const img = new Image();
img.src = 'https://fastly.picsum.photos/id/290/200/300.jpg?hmac=kjRyFwJ6i5kuROjzxcs6QbXbBr8EptbH5AuVxtMxhQ0';
img.onload = (() => {
const canvas = document.querySelector("#image");
const ctx = canvas.getContext('2d');
ctx.drawImage(img, 70, 140, cropSize.width, cropSize.height, 70, 140, cropSize.width, cropSize.height);
});
<!-- language: lang-css -->
#main {
display: flex;
flex-direction: column;
align-items: center;
box-sizing: border-box;
width: 500px;
height: 400px;
}
#container {
flex-grow: 1;
box-sizing: border-box;
border: 1px solid black;
background-color: lightgray;
position: relative;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
#image-and-background {
position: relative;
width: 200px;
height: 300px;
background-color: white;
}
#background::before {
content: '';
background: url('https://fastly.picsum.photos/id/290/200/300.jpg?hmac=kjRyFwJ6i5kuROjzxcs6QbXbBr8EptbH5AuVxtMxhQ0') no-repeat;
opacity: 0.3;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
<!-- language: lang-html -->
<div id='main'>
<div id='container'>
<div id='image-and-background'>
<div id='background'>
<canvas id='image' width='200' height='300'></canvas>
</div>
</div>
</div>
</div>
<div>
<p>Click on the "Crop" button below for a cropped image</p>
<canvas id='cropped' width='100', height='100'></canvas>
<div id='buttons'>
<input type="button" id="button1" onclick="crop()" value="Crop" />
</div>
</div>
<!-- end snippet -->
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论