#javascript #jquery
#javascript #jquery
Вопрос:
Есть идеи, как обрезать созданное изображение и добавить водяной знак?
изображение должно быть квадратным (600 x 600 пикселей), обрезанным посередине, и я должен добавить к нему водяной знак.
Я попробовал этот плагин jqueryhttps://github.com/lelinhtinh/watermark но не работает.
если предварительный просмотр ниже не работает, вы можете посмотреть демонстрацию здесьhttps://jsfiddle.net/y9rhwvgn
любые предложения приветствуются 🙂
// References to all the element we will need.
var video = document.querySelector('#camera-stream'),
image = document.querySelector('#snap'),
start_camera = document.querySelector('#start-camera'),
controls = document.querySelector('.controls'),
take_photo_btn = document.querySelector('#take-photo'),
delete_photo_btn = document.querySelector('#delete-photo'),
download_photo_btn = document.querySelector('#download-photo'),
error_message = document.querySelector('#error-message');
// The getUserMedia interface is used for handling camera input.
// Some browsers need a prefix so here we're covering all the options
navigator.getMedia = ( navigator.getUserMedia ||
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia ||
navigator.msGetUserMedia);
if(!navigator.getMedia){
displayErrorMessage("Your browser doesn't have support for the navigator.getUserMedia interface.");
}
else{
// Request the camera.
navigator.getMedia(
{
video: true
},
// Success Callback
function(stream){
// Create an object URL for the video stream and
// set it as src of our HTLM video element.
video.srcObject=stream;
// Play the video element to start the stream.
video.play();
video.onplay = function() {
showVideo();
};
},
// Error Callback
function(err){
displayErrorMessage("There was an error with accessing the camera stream: " err.name, err);
}
);
}
// Mobile browsers cannot play video without user input,
// so here we're using a button to start it manually.
start_camera.addEventListener("click", function(e){
e.preventDefault();
// Start video playback manually.
video.play();
showVideo();
});
take_photo_btn.addEventListener("click", function(e){
e.preventDefault();
var snap = takeSnapshot();
// Show image.
image.setAttribute('src', snap);
image.classList.add("visible");
// Enable delete and save buttons
delete_photo_btn.classList.remove("disabled");
download_photo_btn.classList.remove("disabled");
// Set the href attribute of the download button to the snap url.
download_photo_btn.href = snap;
// Pause video playback of stream.
video.pause();
});
delete_photo_btn.addEventListener("click", function(e){
e.preventDefault();
// Hide image.
image.setAttribute('src', "");
image.classList.remove("visible");
// Disable delete and save buttons
delete_photo_btn.classList.add("disabled");
download_photo_btn.classList.add("disabled");
// Resume playback of stream.
video.play();
});
function showVideo(){
// Display the video stream and the controls.
hideUI();
video.classList.add("visible");
controls.classList.add("visible");
}
function takeSnapshot(){
// Here we're using a trick that involves a hidden canvas element.
var hidden_canvas = document.querySelector('canvas'),
context = hidden_canvas.getContext('2d');
var width = video.videoWidth,
height = video.videoHeight;
if (width amp;amp; height) {
// Setup a canvas with the same dimensions as the video.
hidden_canvas.width = width;
hidden_canvas.height = height;
// Make a copy of the current frame in the video on the canvas.
context.drawImage(video, 0, 0, width, height);
// Turn the canvas image into a dataURL that can be used as a src for our photo.
return hidden_canvas.toDataURL('image/png');
}
}
function displayErrorMessage(error_msg, error){
error = error || "";
if(error){
console.log(error);
}
error_message.innerText = error_msg;
hideUI();
error_message.classList.add("visible");
}
function hideUI(){
// Helper function for clearing the app UI.
controls.classList.remove("visible");
start_camera.classList.remove("visible");
video.classList.remove("visible");
snap.classList.remove("visible");
error_message.classList.remove("visible");
}
@import url('https://fonts.googleapis.com/css?family=Open Sans:400,700');
@import url('https://fonts.googleapis.com/icon?family=Material Icons');
*{
box-sizing: border-box;
margin: 0;
padding: 0;
}
html{
background-color: #fff;
font:normal 16px/1.5 sans-serif;
color: #333;
}
h3{
font: normal 32px/1.5 'Open Sans', sans-serif;
color: #2c3e50;
margin: 50px 0;
text-align: center;
}
.container{
max-width: 1000px;
margin: 50px auto;
padding: 20px;
background-color: #efefef;
}
.app{
width: 100%;
position: relative;
}
.app #start-camera{
display: none;
border-radius: 3px;
max-width: 400px;
color: #fff;
background-color: #448AFF;
text-decoration: none;
padding: 15px;
opacity: 0.8;
margin: 50px auto;
text-align: center;
}
.app video#camera-stream{
display: none;
width: 100%;
}
.app img#snap{
position: absolute;
top: 0;
left: 0;
width: 100%;
z-index: 10;
display: none;
}
.app #error-message{
width: 100%;
background-color: #ccc;
color: #9b9b9b;
font-size: 28px;
padding: 200px 100px;
text-align: center;
display: none;
}
.app .controls{
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 20;
display: flex;
align-items: flex-end;
justify-content: space-between;
padding: 30px;
display: none;
}
.app .controls a{
border-radius: 50%;
color: #fff;
background-color: #111;
text-decoration: none;
padding: 15px;
line-height: 0;
opacity: 0.7;
outline: none;
-webkit-tap-highlight-color: transparent;
}
.app .controls a:hover{
opacity: 1;
}
.app .controls a.disabled{
background-color: #555;
opacity: 0.5;
cursor: defau<
pointer-events: none;
}
.app .controls a.disabled:hover{
opacity: 0.5;
}
.app .controls a i{
font-size: 18px;
}
.app .controls #take-photo i{
font-size: 32px;
}
.app canvas{
display: none;
}
.app video#camera-stream.visible,
.app img#snap.visible,
.app #error-message.visible
{
display: block;
}
.app .controls.visible{
display: flex;
}
@media(max-width: 1000px){
.container{
margin: 40px;
}
.app #start-camera.visible{
display: block;
}
.app .controls a i{
font-size: 16px;
}
.app .controls #take-photo i{
font-size: 24px;
}
}
@media(max-width: 600px){
.container{
margin: 10px;
}
.app #error-message{
padding: 80px 50px;
font-size: 18px;
}
.app .controls a i{
font-size: 12px;
}
.app .controls #take-photo i{
font-size: 18px;
}
}
<h3>Demo: Take a Selfie</h3>
<div class="container">
<div class="app">
<a href="#" id="start-camera" class="visible">Touch here to start the app.</a>
<video id="camera-stream"></video>
<img id="snap">
<p id="error-message"></p>
<div class="controls">
<a href="#" id="delete-photo" title="Delete Photo" class="disabled"><i class="material-icons">delete</i></a>
<a href="#" id="take-photo" title="Take Photo"><i class="material-icons">camera_alt</i></a>
<a href="#" id="download-photo" download="selfie.png" title="Save Photo" class="disabled"><i class="material-icons">file_download</i></a>
</div>
<!-- Hidden canvas element. Used for taking snapshot of video. -->
<canvas></canvas>
</div>
</div>
Ответ №1:
У меня была готова пара функций для чего-то, над чем я ранее работал. Эти функции масштабируют ваше изображение так, чтобы оно либо помещалось внутри указанных размеров, либо заполняло указанные размеры.
var cat_img = 'https://i.chzbgr.com/maxW500/1691290368/h07F7F378/';
(async function() {
// option one
var fit = await scaleAndFitImage(cat_img, 600, 600);
// option two
var cov = await scaleAndCoverImage(cat_img, 600, 600);
document.body.innerHTML = `
<h3>option 1: fit</h3>
<img src="${fit}" style='border:1px solid black'>
<h3>option 2: scale</h3>
<img src="${cov}" style='border:1px solid black'>
`;
})();
function loadImage(src) {
return new Promise((r, e) => {
var img = new Image();
img.crossOrigin = "anonymous";
img.onload = () => r(img);
img.onerror = e;
img.src = src;
});
}
async function scaleAndFitImage(src, w, h) {
var img = await loadImage(src);
var canvas = document.createElement('canvas');
canvas.width = w;
canvas.height = h;
var ctx = canvas.getContext('2d');
var scale = Math.min(canvas.width / img.width, canvas.height / img.height);
var x = (canvas.width / 2) - (img.width / 2) * scale;
var y = (canvas.height / 2) - (img.height / 2) * scale;
ctx.drawImage(img, x, y, img.width * scale, img.height * scale);
return canvas.toDataURL();
}
async function scaleAndCoverImage(src, w, h) {
var img = await loadImage(src);
var canvas = document.createElement('canvas');
canvas.width = w;
canvas.height = h;
var ctx = canvas.getContext('2d');
var x = y = 0,
offsetX = 0.5,
offsetY = 0.5;
var iw = img.width,
ih = img.height,
r = Math.min(w / iw, h / ih),
nw = iw * r, // new prop. width
nh = ih * r, // new prop. height
cx, cy, cw, ch, ar = 1;
if (nw < w) ar = w / nw;
if (Math.abs(ar - 1) < 1e-14 amp;amp; nh < h) ar = h / nh; // updated
nw *= ar;
nh *= ar;
cw = iw / (nw / w);
ch = ih / (nh / h);
cx = (iw - cw) * offsetX;
cy = (ih - ch) * offsetY;
if (cx < 0) cx = 0;
if (cy < 0) cy = 0;
if (cw > iw) cw = iw;
if (ch > ih) ch = ih;
ctx.drawImage(img, cx, cy, cw, ch, x, y, w, h);
return canvas.toDataURL();
}