How can I resize an image in FabricJS? - fabricjs

I'm trying to resize an image which will then be exported and saved by the user. I've tried the following methods but neither of them are working for me.
The first method is to set the scaleX and scaleY. This does cause the image to be resized within the page, but doesn't seem to truly resize the image. In other words, it is being displayed at the proper size but the image data hasn't changed.
img.set({
scaleX: newWidth/currentWidth,
scaleY: newHeight/currentHeight
});
The other method I tried was using the resize filter. Unfortunately, this doesn't appear to do anything. The other filters I'm using are working fine.
var canvas = new fabric.Canvas('c');
img.filters.push(new fabric.Image.filters.Resize({
resizeType: 'hermite',
scaleX: newWidth/currentWidth,
scaleY: newHeight/currentHeight
}));
img.applyFilters();
canvas.requestRenderAll();
If anyone has any suggestions I'd appreciate it.

The problem was that I needed to obtain the resized image from image._element.toDataURL() rather than calling image.toDataURL().

Related

Using HTML code to detect image size on screen

I'm developing an app that grabs the HTML from a webpage and looks at images, within the HTML, that can be compressed and resized.
I can do the first part no problem in node, using Sharp here:
https://www.npmjs.com/package/sharp
I can, of course, resize the same image here too. I just don't know what dimensions to use. I don't want a tiny image to scale up and so on.
Can I somehow detect the size of the image on screen using the HTML I got to begin with?
Thanks in advance.
EDIT:
Sorry for any confusion. I need to know how big the image is being displayed on the page. So, the image may be 400x400 but the css could limit it to 200x200.
If I have a large image (1000x1000) but it's only being shown on screen at 500x500, I'd know it's a great candidate for resizing.
I'm just not sure how I can resize based on it's css dimensions.
I think in Sharp there's a metadata function that lets you access image metadata, e.g. format, width, height, etc.
Example:
const image = sharp(inputJpg);
image.metadata().then(function(metadata) {
// print image width and height
console.log({
width: metadata.width,
height: metadata.height
});
});
In Sharp library,
You can get dimension from this document:
http://sharp.dimens.io/en/stable/search.html?q=dimension
Hope it will help you.
const sharpImage = sharp('test/test.jpg');
image.metadata().then(function(metadata) {
console.log(metadata);
});

FabricJS Resize filters with canvas zoom

The default behavior of fabricJS resizefilters makes images look great as long as the zoom level is set to 1.0. This means images with a resizefilter look pixelated when zoomed in, as well as when exporting the canvas with a multiplier. Is there a way for resizefilters to take into account the current canvas zoom level or toDataURL multiplier?
https://jsfiddle.net/melchiar/mh9ba4pz/
fabric.Image.fromURL(imageData, function(img) {
img.set({
left: 10,
top: 10
}).scale(0.5);
img.resizeFilter = new fabric.Image.filters.Resize({
resizeType: 'hermite'
});
img.applyResizeFilters();
canvas.add(img);
});
Hi i have seen your question on the issue tracker too, as of now there is no simple way to obtain it with the resize filter.
The only way to make it non pixellated is to remove at export time the resizeFilter and add one resizeFilter in the normal filter chain with a precalculated ratio.
This is actually a bug.
issue tracker: https://github.com/fabricjs/fabric.js/issues/5071
Just an update on this question, this issue was a bug that was fixed with Version 2.3.4. Using a resizefilter will now apply resizing based on the current zoom level, and works with toDataURL multipliers as well.

fabricjs call to canvas.toDataURL() resizes the dimensions of the canvas

I'm using fabricjs 1.7.17 and have seen this issue below on IE Edge, Chrome and Firefox.
where the canvas is being set with a width and height in HTML of 768px.
Within my fabricjs canvas init I've got:
editor.canvas = new fabric.Canvas('editor')
editor.canvas.setDimensions({
width: 1080,
height: 1080,
allowTouchScrolling: false,
backgroundColor: 'rgba(55, 55, 55, .33)',
rotationCursor: 'url(/static/img/rotate.cur) 10 10, crosshair'
}, {backstoreOnly: true})
The problem is when you call the editor.canvas.toDataURL() method the size of the goes from 768px to 1080px
If you call the browser's native canvas.toDataURL() method there isn't a jump in size.
Anyone bump into this and have a possible fix?
Here's a simplified jsfiddle:
https://jsfiddle.net/m8dhmbtu/23/
Click on the "Native Canvas.toDataURL()" and you'll get the results to console.log and there will be no change to the displayed canvas in the preview window.
Click on the "Fabricjs canvas.toDataURL()" and you'll also get the results (the same) to console.log however; you'll also get a jump in the size of the in the preview window...this is what I'm trying to prevent.
I think the problem is actually a bug.
You set the canvas to 1080 for backstore dimension only, meaning that the canvas will be sized but the css will be left untouched.
A dataurl will reset the canvas after the process to fix it back in case the export to data url had a multiplier.
while this can be fixed at least for the non multiplied situations, a proper fix is needed.
The proper fix consist in setting backstore only during export so that the css does not get touched.
A better fix would be to do not touch the original canvas and create one on the fly just for exporting.
please go on official fabricjs repository and open an issue for this.

ImageOverlay and Rectangle Z index issue

I have a function that adds an imageOverlay and a semitransparent Rectangle on top of that image (so as to tint the image, and draw a keyline around it).
activeUserImage = new L.imageOverlay(imageUrl, imageBounds).addTo(map);
activeUserTile = new L.rectangle(imageBounds, {stroke: true, color: "#ffffff", opacity:1, weight: 1, fillColor: "#003572", fillOpacity: 0.7, clickable:true}).addTo(map);
this works great, but then I want to remove the image and rectangle with:
map.removeLayer(activeUserImage);
map.removeLayer(activeUserTile);
This seems to work well...
However when I try and add a second Image & Rectangle (using the same function) the rectangle SVG is being rendered underneath the image, so I don't see the colored overlay.
This seems to be because the element is being left behind from the first creation, and then when the image is being added a second time it appears in front of the SVG.
Q:
Is this a bug? Should the SVG element not be cleared too?
Can I adjust z-index of the image or SVG on creation?
should i be containing to rectangle in a different layer to the images? How?
Many Thanks
OK, so the Leaflet bringToFront() method didn't work, but instead I have used a bit of JQuery to force the same approach.
svgObj = $('.leaflet-overlay-pane svg');
svgObj.css('z-index', 9999);
This works, but still feels like a hack... however if (?) there is a bug in LEaflet, then maybe this will have to do???
Any better ideas?
The bringToFront() function alows you to bring layer to the top.
Search it in the docs.

SuperSleight is scaling my background image

OK I'm using SuperSleight to fix the background transparencies on the png images in ie6. It all works as it should except it is scaling my background image to 100% height.
I have the following set to 100% because I want my footer to stay at the bottom. It seems like this is affecting SuperSleight and is causing my background image to scale. For most people simply changing the background image format would work but Ive worked a fair amount trying to remove gradient rings and using a png came out with the best result. Does anyone know a fix for this?
body, html {
height: 100%;
min-height:100%;
}
body{
background-image:url(../images/content_bg6.png);
background-color:#3e2f24;
background-repeat:repeat-x;
}
I worked around the problem by creating a div wrapper for all the content within the body tag initialized supersleight to that specific wrapper and its children avoiding the body tag.
$(document).ready(function(){
$('#pageWrapper').supersleight();
});
The above is a work around.

Resources