I need to download the image after modification? - javascript

I have a function that change image color to black and white and I want to download the image after changed using button
function preview(file) {
if (file) {
var reader = new FileReader()
reader.readAsDataURL(file);
reader.onloadend = function () {
document.getElementById("img").src = reader.result;
document.getElementById("img").style.filter = "grayscale(100%)";
}
}
}
<input type="file" accept="image/*" onchange="preview(this.files[0])"/>
<br>
<img id="img"/>

There are two things here :
We have to wait for the img.onload function before doing something
We need to copy the filter from the image to the canvas
function downloadImage(imgNode, name = 'fileName', format = 'png') {
const canvas = document.createElement('canvas');
canvas.width = imgNode.width;
canvas.height = imgNode.height;
const context = canvas.getContext('2d');
context.filter = getComputedStyle(imgNode).filter; // Add the image filter to the canvas
imgNode.setAttribute('crossOrigin', 'anonymous');
context.drawImage(imgNode, 0, 0, canvas.width, canvas.height);
const url = canvas.toDataURL(`image/${format}`);
const anchor = document.createElement('a');
anchor.href = url;
anchor.download = `${name}.${format}`;
document.body.appendChild(anchor);
anchor.click();
}
function preview(file) {
if (file) {
var reader = new FileReader()
reader.readAsDataURL(file);
reader.onloadend = function () {
var img = new Image();
img.src = reader.result;
img.style.filter = "grayscale(100%)"; // Apply the CSS filter on the image
document.body.appendChild(img); // Display image
img.onload = function() {
downloadImage(img); // Download image
img.onload = null; // Prevent onload function called twice
};
}
}
}
<input type="file" accept="image/*" onchange="preview(this.files[0])"/>
<br/>

You can do this with Javascript:
First, draw an image in Canvas with CSS and then create anchor tag programmatically and assign click to it
function preview(file) {
if (file) {
var reader = new FileReader()
reader.readAsDataURL(file);
reader.onloadend = function() {
document.getElementById("img").src = reader.result;
var canvas = document.getElementById('cnimage');
var ctx = canvas.getContext('2d');
ctx.filter = "grayscale(100%)"
var img = document.getElementById("img");
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
anchor = document.createElement('a');
document.body.appendChild(anchor);
anchor.download = name;
var data = canvas.toDataURL("image/png");
anchor.href = data;
anchor.click();
ctx.clearRect(0, 0, canvas.width,canvas.height);
}
}
}
<input type="file" accept="image/*" onchange="preview(this.files[0])"/>
<br>
<img id="img"/>
<canvas id="cnimage" height="400px" width="400px"></canvas>

Related

How can I resize an image before uploading via form input in Angular?

I tried resizing an image before uploading and sometimes it works and sometimes not.
<form [formGroup]="uploadForm" (ngSubmit)="upload()">
<input type="file" id="file" formControlName="file" (change)="onImageChange($event)">
<div class="contentMainInput" *ngIf="imgFile">
<img [src]="imgFile" style="height:100px">
</div>
<button type="submit" [disabled]='!uploadForm.valid'>Upload</button>
</form>
onImageChange(e: any) {
const reader = new FileReader();
if(e.target.files && e.target.files.length) {
const imgfile = e.target.files[0];
reader.readAsDataURL(imgfile);
reader.onload = () => {
this.imgSrc = reader.result as string;
const img = document.createElement("img");
const canvas = document.createElement("canvas");
img.src = this.imgSrc;
canvas.width = 100;
canvas.height = 100;
const ctx = canvas.getContext("2d") as CanvasRenderingContext2D;
ctx.drawImage(img, 0, 0, 100, 100); // image resize to 100x100
this.dataUrl = canvas.toDataURL("image/jpeg", 1.0);
this.imgFile = this.dataUrl; // bind with a preview-div
this.uploadForm.patchValue({
imgSrc: this.dataUrl
});
};
}
}
I guess if i put some console.log in the code it works frequent.
I also tried it with img.onload, but then I have no access to global variables like this.uploadForm.
So I'm looking for a code to do this:
an image can be selected by a form
the image will be resized
the resized image will be previewed at the site
the resized image gets uploaded after submitting
This seems to work well now:
onImageChange(e: any) {
const reader = new FileReader();
if(e.target.files && e.target.files.length) {
const imgfile = e.target.files[0];
reader.readAsDataURL(imgfile);
reader.onload = async () => {
await this.resizeImage(reader.result as string).then((resolve: any) => {
this.imgFile = resolve;
this.uploadForm.patchValue({
imgSrc: resolve
});
});
};
}
}
resizeImage(imageURL: any): Promise<any> {
return new Promise((resolve) => {
const image = new Image();
image.onload = function () {
const canvas = document.createElement('canvas');
canvas.width = 200;
canvas.height = 200;
const ctx = canvas.getContext('2d');
if (ctx != null) {
ctx.drawImage(image, 0, 0, 200, 200);
}
var data = canvas.toDataURL('image/jpeg', 1);
resolve(data);
};
image.src = imageURL;
});
}

how can i put base64 image file into opencv? (javascript)

I'm trying to get random image from input video file, and then put the image into opencv to get grayScale image on the webpage.
Getting random image from video is solved by below-solution.
Javascript how to extract frame from video?
but now i'm stuck to the problem, Is it impossible to give base 64 source image file into opencv(imread, imshow, cv.cvtColor)? Please help me.
'''
//const cv = require("./js/opencv");
var video = document.createElement("video");
var image = new Image();
var canvas = document.getElementById("prevImgCanvas");
var canvas_after = document.getElementById("canvas_after");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
video.addEventListener('loadeddata', function() {
reloadRandomFrame();
}, false);
video.addEventListener('seeked', function() {
var context = canvas.getContext('2d');
context.drawImage(video, 0, 0, canvas.width, canvas.height);
const dataurl = canvas.toDataURL("image/jpeg")
image.src = dataurl;
image.onload = function(){
console.log(image);
let mat = cv.imread(image);
cv.imshow('canvasOutput', mat);
mat.delete();
};
}, false);
var playSelectedFile = function(event) {
var file = this.files[0];
var fileURL = URL.createObjectURL(file);
video.src = fileURL;
}
var input = document.getElementById('fileinput');
input.addEventListener('change', playSelectedFile, false);
function reloadRandomFrame() {
if (!isNaN(video.duration)) {
var rand = Math.round(Math.random() * video.duration * 1000) + 1;
video.currentTime = rand / 1000;
}
}
'''
let image = new Image()
image.src = 'your base64'
await new Promise(r => {
image.onload = r
})
cv.imread(image)

How to merge multiple uploaded images by using Multi File Upload control?

I am trying to merge multiple images while retrieving the images from desk. It was taken from "How to create an image generator for combining multiple images?". It's working fine if single image is uploaded, but not working in case of multiple images.
This is my HTML code
<input id="file-input" type="file" name="images[]" multiple maxlength="5" ngf-select="UploadFiles($files)" accept=".png,.jpg,.jpeg,.gif" />
<canvas id="canvas"></canvas>
This is javascript code
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var lastImage;
var lastHeight = 0;
var lastWidth = 0;
var imagesLoaded = 0;
function max(a, b) {
if (a > b)
return a;
return b;
}
function addToCanvas(img) {
canvas.height = max(lastHeight, img.width);
canvas.width = lastWidth + img.height;
ctx.clearRect(0, 0, canvas.width, canvas.height);
if (lastImage) {
ctx.drawImage(lastImage, 0, canvas.height - lastImage.height);
}
ctx.rotate(270 * Math.PI / 180); // rotate the canvas to the specified degrees
ctx.drawImage(img, -canvas.height, lastWidth);
lastImage = new Image();
lastImage.src = canvas.toDataURL();
lastWidth += img.height;
lastHeight = canvas.height;
imagesLoaded += 1;
}
$scope.UploadFiles = function (files) {
$scope.SelectedFiles = files;
cnt = files.length;
console.log($scope.SelectedFiles);
for (i = 0; i < $scope.SelectedFiles.length; i++) {
console.log(files[i]);
var reader = new FileReader();
reader.onload = function (event) {
var img = new Image();
img.onload = function () {
addToCanvas(img);
}
img.src = reader.result;
}
reader.readAsDataURL(files[i]);
}
};
When I select images from the folder, the console's debugger stops at img.onload event, where I am trying to do action in loop.
For loop iteration not working for imageload functions..
files.map((file) => {
var reader = new FileReader();
reader.onload = (event) => {
var img = new Image();
img.onload = () =>
{
addToCanvas(img);
}
img.src = reader.result;
}
reader.readAsDataURL(file);
}
)

getImageData returns white image

I need to read the image data from an image object in javascript.
But my code returns always a blank array (set to 255)
<html>
<header>
</header>
<body>
<input type="file" id="imgfile" onchange="testImageData(event);" />
<canvas id="canvas1" width="640" height="480"></canvas>
<script src="./../scripts/cam.js" ></script>
</body>
</html>
Here is the script
var canvas1 = document.getElementById('canvas1');
var context1 = canvas1.getContext('2d');
function getImageData(image){
/*
returns Uint8ClampedArray object
takes an image obj
*/
var canvas = document.createElement("canvas");
canvas.height = image.height;
canvas.width = image.width;
var ctx = canvas.getContext("2d");
ctx.width = image.width;
ctx.height = image.height;
ctx.drawImage(image,0,0);
return ctx.getImageData(0, 0, ctx.width, ctx.height);
}
function testImageData(event){
var selectedFile = event.target.files[0];
var reader = new FileReader();
var img = new Image();
reader.onload = function(event) {
console.log('onload');
img.src = event.target.result;
img.onload = function(){
context1.drawImage(img, 0,0, img.width, img.height);
var imgData = getImageData(img);
// console.log(imgData);
var data = imgData.data;
for(var i = 0; i<data.length;i+=4){
console.log(data[i],data[i+1],data[i+2],data[i+3]);
}
}
};
In my understanding, the console.log should return me the data in RGBA.
But I'm just getting 255.
console.log output
EDIT:
Okay I found a work around but I don't understand why this is working.
Instead using getImageData, I get the data directly from the drawn context1.
function testImageData(event){
var selectedFile = event.target.files[0];
var reader = new FileReader();
var img = new Image();
reader.onload = function(event) {
console.log('onload');
img.src = event.target.result;
img.onload = function(){
context1.drawImage(img, 0,0, img.width, img.height);
var imgData = context1.getImageData(0,0,img.width,img.height);
var data = imgData.data;
for(var i = 0; i<data.length;i+=4){
console.log(data[i],data[i+1],data[i+2],data[i+3]);
}
}
};
So the problem must lie in creating a new canvas.
You should wait for the image to load img.onload you are waiting for the readers onload event...
you also forget to read the file... missed reader.readAsDataURL
but you don't need the filereader.
window.URL = window.URL || webkitURL
var img = new Image();
img.src = URL.createObjectURL(file)
img.onload = function(){
// put your image on the canvas
}

Take a snapshot from a data-uri video

I'm trying to get a snapshot from a video data-uri
var video = document.createElement('video');
video.src = uri;
canvas = document.createElement('canvas');
canvas.style.visibility = 'hidden';
document.body.appendChild(canvas);
var context = canvas.getContext('2d');
context.drawImage(video, 0, 0, canvas.width, canvas.height);
var snapshot = canvas.toDataURL();
But this doesn't work. Why?
Although it's a Data URI and you might expect the video to load instantly, you do need to listen for the video's canPlay event (see MDN).
function onFile(ev) {
var file = ev.target.files[0];
console.log();
var reader = new FileReader();
reader.addEventListener('load', function() {
taksVideoSnapshot(reader.result);
}, false);
reader.readAsDataURL(file);
}
function taksVideoSnapshot(videoUri) {
var video = document.createElement('video');
video.addEventListener('canplay', function() {
canvas = document.createElement('canvas');
canvas.style.visibility = 'hidden';
document.body.appendChild(canvas);
var context = canvas.getContext('2d');
context.drawImage(video, 0, 0, canvas.width, canvas.height);
var snapshot = canvas.toDataURL();
console.log('Snapshot', snapshot.length);
showThumb(snapshot);
}, false);
video.src = videoUri;
document.body.appendChild(video);
}
function showThumb(snapshot) {
var thumb = document.createElement('img');
thumb.src = snapshot;
document.body.appendChild(thumb);
}
<input type="file" onchange="onFile(event)">
Also see on JSBin.

Categories

Resources