I'm currently trying to add watermark to an image, and I'm using this script:
function mixImages(){
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
var imageObj1 = new Image();
var imageObj2 = new Image();
var marginTop = 10;
var marginLeft = 10;
imageObj1.src = "http://localhost:8080/sisop/storage/app/public/files/16522147787.png"
imageObj1.onload = function() {
ctx.drawImage(imageObj1, 0, 0, 328, 526);
imageObj2.src = "http://localhost:8080/sisop/storage/app/public/files/165221397618.png";
imageObj2.onload = function() {
ctx.drawImage(imageObj2, marginLeft, marginTop, 100, 100);
var img = c.toDataURL("image/png");
}
};
}
Which works fine if I'm only doing it with 1 canvas. But I'm trying to do this dynamically to every image that is loaded in my PHP code. so I'm trying to do this:
foreach($collection as $file){
echo "
<div class='posts-cards'>
<canvas id='myCanvas$file->id' width='300' height='300'></canvas>
</div>
<script>
var c=document.getElementById('myCanvas$file->id');
var ctx=c.getContext('2d');
var imageObj1 = new Image();
var imageObj2 = new Image();
var marginTop = 10;
var marginLeft = 10;
imageObj1.src = 'http://localhost:8080/sisop/storage/app/public/files/16522147787.png'
imageObj1.onload = function() {
ctx.drawImage(imageObj1, 0, 0, 328, 526);
imageObj2.src = 'http://localhost:8080/sisop/storage/app/public/files/165221397618.png';
imageObj2.onload = function() {
ctx.drawImage(imageObj2, marginLeft, marginTop, 100, 100);
var img = c.toDataURL('image/png');
}
};
</script>
But for some reason, the result is this:
I have "display: flex; flex-flow: wrap; " in my css (it's supposed to be 2 rows of 4 items in each), so, for some reason, only the 5th and 8th image are being generated.. And as you can see, only the last image has actually "merged" with the other image. I'm pretty stuck in here and don't quite understand what is going on here..
Related
This question already has answers here:
Callback/scope understanding
(3 answers)
Closed 1 year ago.
I am having trouble drawing an image with CSS filters onto a canvas. I want to apply the CSS filters with sliders/range inputs that I have. The image that the filters will be applied to is an image that you upload from your files. This image is put into a variable in a function I have that will upload the image. The function for the slider is separate, and therefore I can't apply the filters and draw the image again in the function that is activated when the sliders are being dragged.
I need it to be drawn instead of just putting the filters on the canvas itself so that I can download the image with filters.
Here is the javascript code:
var imageLoader = document.getElementById('imageLoader');
imageLoader.addEventListener('change', handleImage, false);
var canvas = document.getElementById('imageCanvas');
var ctx = canvas.getContext('2d');
function handleImage(e) {
var reader = new FileReader();
reader.onload = function(event) {
var img = new Image();
img.onload = function() {
var ratio = this.height / this.width;
canvas.height = canvas.width * ratio;
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
}
img.src = event.target.result;
}
reader.readAsDataURL(e.target.files[0]);
}
var container = document.getElementById("container")
var download = document.getElementById("download")
var adjustments = document.getElementById("adjustments")
download.addEventListener("click", function() {
var link = document.createElement('a');
link.download = 'filename.png';
link.href = canvas.toDataURL();
link.click();
});
var prop1 = document.getElementById("prop1");
var open = true;
adjustments.addEventListener("click", function() {
if (open === true) {
prop1.style = "margin-left: -240px;";
adjustments.classList.remove("line");
open = false;
} else if (open === false) {
prop1.style = "margin-left: 50px;";
adjustments.classList.add("line");
open = true;
}
});
var contrast = document.getElementById("contrast");
var brightness = document.getElementById("brightness");
var slider1 = contrast.value;
var slider2 = brightness.value;
function effect() {
slider1 = contrast.value;
slider2 = brightness.value;
ctx.filter = "contrast(" + slider1 + ") brightness(" + slider2 + ")";
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
}
contrast.oninput = function() {
effect()
};
brightness.oninput = function() {
effect()
};
You could try clearing the canvas with ctx.clearRect() then redraw everything on the canvas. I'd also recommend creating a function to redraw the items just for easier reading.
I would like to combine two images (one uploaded from the device and another from the website) and export them as one image. The image uploaded from the device would be the background image and the one from the website is a logo to make in to a watermark in the bottom corner.
Is this possible and if so where should I start?
Thank you
I have been able to add an image on top of another image using the Javascript code below:
function watermarkLogo(elemImage) {
var canvas = document.getElementById("canvas");
canvas.width = elemImage.naturalWidth;
canvas.height = elemImage.naturalHeight;
var myVar = canvas.getContext("2d");
var img1 = loadImage(elemImage.src, myFunction);
var img2 = loadImage('icon.png', myFunction);
var numberOfImages = 0;
function myFunction() {
numberOfImages += 1;
if(numberOfImages == 2) {
myVar.drawImage(img1, 0, 0);
myVar.globalAlpha = 0.5;
var widthOffset = (canvas.width/3)*2;
var heightOffset = (canvas.height/3)*2;
myVar.drawImage(img2, widthOffset-50, heightOffset-50, 100, 100);
}
}
function loadImage(src, onload) {
var img = new Image();
img.onload = onload;
img.src = src;
return img;
}
}
In my current code I have different functions to draw different canvases, these work perfectly. The draw function will be called a number of times and store the result to be called later, once the image is finalised.
I cannot get the two images to merge together. I can redraw them individually in mergeCanvas(), by calling 'testbor1.url' but when I try to draw them onto a new canvas, the result is blank.
Can anyone tell me why I cannot draw these onto one canvas?
Following: How can I put multiple canvas elements in to one canvas element?
function draw()
{
var can3 = document.getElementById('RugCanvas3');
can3.offset = 0;
can3.width = namespacetest.getCanvasWidth();
can3.height = namespacetest.getCanvasHeight();
var ctx3 = can3.getContext('2d');
ctx3.drawImage(drawBorder(70,size,img, borderwidth), 0, 0);
ctx3.drawImage(drawOverlay(borderwidth, 70), 0, 0);
var img = new Image();
img.src = can3.toDataURL("image/png");
namespacetest.dataURLs['img1'] = img.src;
}
namespacetest.mergeCanvas = function()
{
var testbor1 = new Image();
var testbor2 = new Image();
testbor1.src = namespacetest.dataURLs['img1'];
testbor2.src = namespacetest.dataURLs['img2'];
var bor = document.getElementById('Canvas5');
var ctx = bor.getContext("2d");
ctx.drawImage(testbor1, 0, 0, 400, 400);
ctx.drawImage(testbor2, 0, 0, 400, 400);
var buffer_img = new Image();
buffer_img.src = bor.toDataURL("image/png");
var output = document.getElementById('RugCanvas6');
output.innerHTML = '<img src="' + buffer_img.src + '" alt="Canvas Image" />';
}
I am adding my cropped image and logo on fabric canvas, cropped image and logo are lower and upper canvas. Now the problem is how to set max width to fabric canvas so that i can drag logo through out the canvas.
I have implemented max width to existing canvas, logo and cropped image. Here the problem is i am unable to drag the logo to entire canvas.
Here is the code
<div class="container">
<div style="position: relative;" id="editor">
<canvas id="canvas" class="img-responsive"></canvas>
</div>
<div class="container">
<a class="btn btn-primary" id="save">Save</a>
<a class="btn btn-primary" id="download">Download</a>
<script>
$(function () {
var source = sessionStorage.getItem("source");
$("#background").attr("src", source);
});
setTimeout(function () {
var myImg = document.querySelector("#background");
var realWidth = myImg.naturalWidth;
var realHeight = myImg.naturalHeight;
$("canvas").attr("width", realWidth);
$("canvas").attr("height", realHeight);
var source = document.getElementById('background').src;
var canvas = new fabric.Canvas('canvas');
canvas.width=realWidth;
canvas.height=realHeight;
var ctx = canvas.getContext('2d');
var img = new Image();
img.src = 'images/logo.png';
var imgInstance = new fabric.Image(img, {
width: 200
, height: 45
});
canvas.add(imgInstance);
canvas.setBackgroundImage(source, canvas.renderAll.bind(canvas), {
backgroundImageOpacity: 0.5
, backgroundImageStretch: false
});
}, 2000);
$("#save").click(function(){
function blobCallback(iconName) {
return function (b) {
var a = document.getElementById('download');
a.download = iconName + ".jpg";
a.href = window.URL.createObjectURL(b);
}
}
canvas.toBlob(blobCallback('wallpaper'), 'image/vnd.microsoft.jpg', '-moz-parse-options:format=bmp;bpp=32');
});
being a fabricjs canvas, do not manipulate width and height directly but use the proper method:
setTimeout(function () {
var myImg = document.querySelector("#background");
var realWidth = myImg.naturalWidth;
var realHeight = myImg.naturalHeight;
var source = document.getElementById('background').src;
var canvas = new fabric.Canvas('canvas');
canvas.setDimensions({ width: realWidth, height: realHeight });
var img = new Image();
// use a load callback to add image to canvas.
img.src = 'images/logo.png';
var imgInstance = new fabric.Image(img, {
width: 200
, height: 45
});
canvas.add(imgInstance);
canvas.setBackgroundImage(source, canvas.renderAll.bind(canvas), {
backgroundImageOpacity: 0.5
, backgroundImageStretch: false
});
}, 2000);
I am trying to convert html into a pdf client side using jspdf.
The code I have currently is this: (most of this is for pagebreaks
$(document).ready(function() {
$("#runpdf").click(function(event) {
var partsec = $("main_body page1");
html2canvas(document.body, {
logging: true,
profile: true,
allowTaint: true,
letterRendering: true,
onrendered: function(canvas) {
var imageData = canvas.toDataURL("image/jpeg");
var image = new Image();
image = Canvas2Image.convertToJPEG(canvas);
var doc = new jsPDF();
doc.page=1;
//FIRST PAGE****************************************
doc.addImage(imageData, 'JPEG', -115, 5, 440 , 875);
var croppingYPosition = 1250;
count = (image.height) / 3300;
for (var i =1; !(i >= count); i++) {
doc.addPage();
var sourceX = 0;
var sourceY = croppingYPosition;
var sourceWidth = image.width;
var sourceHeight = 1100;
var destWidth = 1600;
var destHeight = 1090;
var destX = -450
var destY = 0;
var canvas1 = document.createElement('canvas');
canvas1.setAttribute('height', 1200);
canvas1.setAttribute('width', destWidth);
var ctx = canvas1.getContext("2d");
ctx.drawImage(image,
sourceX,
sourceY,
sourceWidth,
sourceHeight,
destX,
destY,
destWidth,
destHeight);
var image2 = new Image();
image2 = Canvas2Image.convertToJPEG(canvas1);
image2Data = image2.src;
doc.addImage(image2Data, 'JPEG', 12, 10);
croppingYPosition += 1230;
}
doc.save('test.pdf');
}
});
});
});
However, I would like to, rather than using arbitrary, hard-coded pixel values for setting pagebreaks, have it search for a specific html tag, id, class, or some other identifier to search for at which to make a page break. For example, The code looks down the html until it finds something of class .pagebreak at which point it takes everything above it and stretches it to fit a pdf page (I can do the stretchy part, I just need help with the actual page break) and then looks right after the page break and starts over. Hope this made sense. Thanks!