Chrome extension screenshot partial image cropping for Retina Display - javascript

I made a chrome extension, which captures a single element (div) of a website.
I used chrome.tabs > captureVisibleTab to make a screenshot. Then, with the coordinates (x/y) and sizes (width/height) of the element (div) I crop the screenshot.
This works fine for me on non-retina displays. But not so on a Macbook with Retina display.
For example, on www.247activemedia.com, we want to capture the header div with the logo (id="header").
On non-retina result is:
On a Macbook with Retina display:
Cropping failed there, and also the resultion is not correct.
Here is the code:
chrome.tabs.captureVisibleTab(tab.windowId, { format: "png" }, function(screenshot) {
if (!canvas) {
canvas = document.createElement("canvas");
document.body.appendChild(canvas);
}
var partialImage = new Image();
partialImage.onload = function() {
canvas.width = dimensions.width;
canvas.height = dimensions.height;
var context = canvas.getContext("2d");
context.drawImage(
partialImage,
dimensions.left,
dimensions.top,
dimensions.width,
dimensions.height,
0,
0,
dimensions.width,
dimensions.height
);
var croppedDataUrl = canvas.toDataURL("image/png");
chrome.tabs.create({
url: croppedDataUrl,
windowId: tab.windowId
});
}
partialImage.src = screenshot;
});
How can I fix this for Retina Displays?

Ok, thanks to #gui47 -- the answer is to detect scale with window.devicePixelRatio which is returning 2 on my MBP

How about this, it works for me.
let ratio = window.devicePixelRatio;
context.drawImage(image,
dimensions.left*ratio, dimensions.top*ratio,
dimensions.width*ratio, dimensions.height*ratio,
0, 0,
dimensions.width, dimensions.height
);
CanvasAPI: https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/drawImage

Related

How to render image on canvas in reactjs

I have added crop image function in my app using react-image-crop but the problem is when i try to crop the image it does not render the right image position on preview I have no idea why. I don't have any experience using canvas before.
This is how My image looks like.
My code to render image on canvas looks something like this.
export function image64toCanvasRef (canvasRef, image64, pixelCrop) {
console.log('imagePixelCrop', pixelCrop);
let canvas = canvasRef // document.createElement('canvas');
canvas.width = pixelCrop.width
canvas.height = pixelCrop.height
const ctx = canvas.getContext('2d')
const image = new Image()
image.src = image64
image.onload = function () {
ctx.drawImage(
image,
pixelCrop.x,
pixelCrop.y,
pixelCrop.width,
pixelCrop.height,
0,
0,
pixelCrop.width,
pixelCrop.height
)
}
}
Here this is i m getting in pixel crop.
aspect: undefined
height: 92.5
unit: "px"
width: 164.5
x: 70
y: 71
https://github.com/DominicTobias/react-image-crop
shows a demo of the same you are trying to acheive have a look
https://codesandbox.io/s/72py4jlll6?file=/src/index.js:1086-1099

HTML 5 Canvas] Image quality when I resize

thank you for taking a look.
What I am trying to do here is... load image from computer (by using FileReader), put img tag's src to the file. Then draw canvas with that image.
function previewFile(){
var preview = document.querySelector('img'); //selects the query named img
var file = document.querySelector('input[type=file]').files[0]; //sames as here
var reader = new FileReader();
reader.onload = function () {
preview.src = reader.result;
drawCanvas();
}
if (file) {
reader.readAsDataURL(file); //reads the data as a URL
} else {
preview.src = "sample.jpg";
}
}
previewFile(); //calls the function named previewFile
window.onload = function () {drawCanvas(); };
function drawCanvas() {
var img = document.querySelector("img");
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext('2d');
ctx.filter = window.getComputedStyle(document.querySelector("img")).filter;
ctx.drawImage(img, 0, 0);
}
Problem is when I load another image file. It loads in the canvas, but not fit in the canvas size. It keeps the original image size and "part" of the image is shown in the canvas.
In order to solve it, I tried following:
ctx.drawImage(img, 0, 0, document.getElementById('canvas').width,
document.getElementById('canvas').height);
It works, however the image quality becomes really bad... since it is not original image size. It is adjusted to the certain height and forced to be resized.
All I want to do is... keep the original canvas size (width: some px; height: auto), so when I load the image, it fits to the canvas width and adjusted height.
Would you please help me? Thank you.
Added
I researched myself and found following:
I came up with an idea - change the image size first based on the current width of the canvas.
var img = document.querySelector("img");
var canvas = document.getElementById("image");
var ratio = img.height / img.width;
img.width = canvas.offsetWidth;
img.height = img.width * ratio;
Then draw with the edited image.
var ctx = canvas.getContext('2d');
ctx.filter = window.getComputedStyle(img).filter;
ctx.drawImage(img, 0, 0, img.width, img.height);
Then I found the problem. I checked "img.height" variable is 199px. But canvas's height becomes 150px somehow. I checked and there is no css applied to the canvas at all.
So this time, I set canvas width, before drawImage().
ctx.canvas.width = img.width;
ctx.canvas.height = img.height;
ctx.filter = window.getComputedStyle(img).filter;
ctx.drawImage(img, 0, 0);
And again, the original image coming back... and "part" of the image is shown in the canvas. The canvas's size is what I wanted though...
Thank you so much for taking a look the issue. Especially #Kaiido who tried to help. Thank you. I am really new to this stackoverflow... so I didn't know how to create demo.
I found the solution. Well... it was really basic knowledge of the Canvas,,, but I think many people will forget / miss following:
var ctx = canvas.getContext('2d');
ctx.canvas.width = 1000;
ctx.canvas.height = 1000;
ctx.drawImage(img, 0, 0, 800, 800);
ctx.canvas.width is canvas's width. ctx.canvas.height is canvas's height.
In drawImage, those 800s are width and height of the image will be drawn, not the canvas's size!! So if you set... let's say 1000, 1000 in drawImage, the image will be resized to the size and it will be drawn into the canvas. If it is bigger than the canvas size, it will show only "part" of your image.
So what I did was... get the div width size where I want to put my canvas. Then calculate the ratio of the image first ( ratio = image's height / image's width ). Then set canvas size to following ( ctx.canvas.width = div width size, ctx.canvas.height = div width size * ratio ). Then draw canvas with canva's width and height ( ctx.drawImage(img, 0, 0, ctx.canvas.width, ctx.canvas.height) ).
Hope this helps someone new like me :) Thank you.
This is pretty simple!
try this.
getting the ratio, setting the height, drawing the image
var ratio = img.naturalWidth / img.naturalHeight;
var width = canvas.width;
var height = width / ratio;
ctx.drawImage(img, 0, 0, width, height);
this worked for me, try this.
see the line
var width = canvas.width;
you can replace the canvas.width by any other value.

Canvas & Color-Thief image index size

I'm using color-thief to analyze the colors of images. I'm using a canvas and getImageData, I'm getting the following error message in the console:
Error: Index or size is negative or greater than the allowed amount
CanvasImage.prototype.getImageData#http://localhost:3000/js/color-thief.js:51:12
ColorThief.prototype.getPalette#http://localhost:3000/js/color-thief.js:109:22
ColorThief.prototype.getColor#http://localhost:3000/js/color-thief.js:75:25
colorController/this.getColors#http://localhost:3000/js/ang.js:20:22
I'm not sure if this is a canvas issue coming from image pixel size or if it's some bug in another library (I'm also using AngularJS) but I'm stuck and not sure what I can do.
I think there is an issue with pixel count being 0, when I add the console.log line to the following code inside color-thief.js then I get "0 0" for some images.
Crucial point --> the image.width and image.height show 0 only for SOME images, while the rest it shows ratios that make sense like 1280 922 or 2000 1333.
var CanvasImage = function (image) {
this.canvas = document.createElement('canvas');
this.context = this.canvas.getContext('2d');
document.body.appendChild(this.canvas);
this.width = this.canvas.width = image.width;
this.height = this.canvas.height = image.height;
console.log(image.width, image.height);
this.context.drawImage(image, 0, 0, this.width, this.height);
};
Any idea why this can happen?
The answer was to add the image.addEventListener("load", function() { ... } to the code to load the image correctly.

Using canvas to draw image at true size

I'm trying to load an image from a URL into a HTML canvas at a 1:1 scale. I load the image, and set the canvas DOM element to the appropriate dimensions, but for some reason the image in the canvas is significantly upscaled and therefore only the top left hand corner is drawn.
This is demonstrated by the following JSFiddle: http://jsfiddle.net/KdrYr/1/
var img = new Image();
var cv = document.getElementById('thecanvas');
img.src = 'http://www.photographyblogger.net/wp-content/uploads/2009/12/Picture-in-a-picture4.jpg';
img.onload = function() {
var ctx = cv.getContext('2d');
cv.style.width = img.width + 'px';
cv.style.height = img.height + 'px';
ctx.drawImage(img, 0, 0);
};
For example, I'm trying to draw this (sorry about the big images :/)
But end up with this
What could be causing this?
You need to assign the canvas actual width and height, not via its style:
cv.width = img.width;
cv.height = img.height;
Live test case.
As for the why, well, it's explained already here.

FlashCanvas drawImage NotWorking

I'm on Windows7 IE9 running in IE8. This works in IE9 only because I can use canvas however in IE8 it's suppose to fall back to flash canvas. Here is my source http://blog.jackadam.net/2010/alpha-jpegs/ NOW it seems im having a problem in IE with the context.drawImage not drawing the image? I've posted on the flashcanvas google group but they seem to take some time to repsond so was hoping there maybe a flashcanvas guru here.
;(function() {
var create_alpha_jpeg = function(img) {
var alpha_path = img.getAttribute('data-alpha-src')
if(!alpha_path) return
// Hide the original un-alpha'd
img.style.visiblity = 'hidden'
// Preload the un-alpha'd image
var image = document.createElement('img')
image.src = img.src + '?' + Math.random()
console.log(image.src);
image.onload = function () {
console.log('image.onload');
// Then preload alpha mask
var alpha = document.createElement('img')
alpha.src = alpha_path + '?' + Math.random()
alpha.onload = function () {
console.log('alpha.onload');
var canvas = document.createElement('canvas')
canvas.width = image.width
canvas.height = image.height
img.parentNode.replaceChild(canvas, img)
// For IE7/8
if(typeof FlashCanvas != 'undefined') FlashCanvas.initElement(canvas)
// Canvas compositing code
var context = canvas.getContext('2d')
context.clearRect(0, 0, image.width, image.height)
context.drawImage(image, 0, 0, image.width, image.height)
//context.globalCompositeOperation = 'xor'
//context.drawImage(alpha, 0, 0, image.width, image.height)
}
}
}
// Apply this technique to every image on the page once DOM is ready
// (I just placed it at the bottom of the page for brevity)
var imgs = document.getElementsByTagName('img')
for(var i = 0; i < imgs.length; i++)
create_alpha_jpeg(imgs[i])
})();
The solution to this was it only works with the older version of flashcanvas AND it only works with flashcanvas pro... as noted in the second footer of the website
This technique uses the globalCompositeOperation operation, which
requires FlashCanvas Pro. Free for non-profit use or just $31 for a
commercial license.
I got it working with flashcanvaspro. Depending which flash player it targets the max image size varies.
Flash Player 10 increased the maximum size of a bitmap to a maximum pixel count of 16,777,215.
Flash Player 9 limits (2880 x 2880 pixels).
https://helpx.adobe.com/flash-player/kb/size-limits-swf-bitmap-files.html
Need someone to update flashcanvas to the latest flash player

Categories

Resources