I'm trying to export an image (PNG) which is larger than the maximum canvas size. I've tiled the canvas export, so that each tile is small enough to be generated (with toBlob). Now I need a way to merge the images together, but can't find a way that itself doesn't use a canvas. Is this possible somehow?
Kaiido's answer worked great. I'm tiling the canvas export with getImageData (moving the contents of the canvas for each tile), then loop over all ImageData tiles & creating a new 1D array of RGBA values which I send to fast-png's encode. It's not very fast, especially on mobile (a ~30MP image takes about 40s to merge on an iPhone X), but I'm doing it on a background thread with a Worker.
Related
We want to load heavy SVG's JSON object (around 10k vector object) into the canvas. Right now we are able to do but the process is lagging very much due to numbers of vector object in canvas. Below is the flow we are following
Load SVG which is saved in the database as the JSON object in the
canvas
So the user can edit.
Convert the canvas in SVG.
Save the edited SVG in the database as the JSON object.
This is working fine when vector objects are less in number (less than 2K), but when the number goes high, system start lagging and some it crashed. We want to manage around 15k - 20k vector objects. We are using fabricjs for this.
->
Try to use the last version of fabricjs (2.3). It use a canvas for caching the path. This how the path is drawed only when you resize it.
There are lots of scripts and plugins on the web for Javascript image crop/resize. Some using the HTML5 canvas to crop a certain area and storing the image back to the client via DataUrl. But without canvas I tested the jrac jquery plugin, but it only provides the cropping coordinates (x, y, width, height) in the end. There is never called an actual cropping function on the image.
How do I actually use these cropping coordinates on the Javascript image object? Can I only use CSS to show the image like being cropped or can I actually crop data out of that image into a new image in Javascript?
It seems to me that all Image crop plugins only provide a handy UI to get crop coordinates but the actual crop/resize must be done server-side with the image being sent to a php script, is that correct?
My question is the same as this one, that has not been answered yet.
Everything is possible in javascript (well almost everything)
To crop an image you need to side step the DOM and built in image handling API's and decode the image yourself. A lot of extra work involved but there is some help out there. A quick search on github found decoders/encoders for both jpg and png formats Image decoders (I am sure there are plenty more about) so with a little work you should be able to modify them to do some cropping.
What you're asking for is a library to read image data to 2d array of pixels (or a 1d array of pixels in case of the canvas), crop the pixels, and write it back to compressed image data.
Sorry to say but that library is the canvas. You can, of course, use css to fake it but all the image data is still there, you're just choosing to only show part of it.
You can try the below one ,But its using Canvas for rendering,
As of now there is no good lib available without canvas becuase it is very difficult to capture the point you selected and to do processing the thousands and thousands of pixels without Graphics Card ,
Canvas only having the functionality to use Graphics Card
intel and firefox is doing some concepts regarding this to introduce parallel processing in javascript
https://github.com/fengyuanchen/cropper/
Yes this is possible with createImageBitmap
Syntax:
createImageBitmap(image)
createImageBitmap(image, options)
createImageBitmap(image, sx, sy, sw, sh)
createImageBitmap(image, sx, sy, sw, sh, options)
See: https://developer.mozilla.org/en-US/docs/Web/API/createImageBitmap
I'm working on a 2d isometric map with HTML5 and canvas.
So, i can have a map with an infinity of tiles, but, I only displayed the tiles around the player and it's my problem.
When i retrieve the image with toDataURL(), I just retrieves the small part of the map that I displayed around the player...
I need to retrieve all the canvas, even that is not displayed, is it possible ?
No, it's not possible. toDataURL do give you the whole canvas but the whole canvas is simply what you see on the screen. Canvas does not know about anything outside this (anything drawn outside the canvas is clipped and forgotten).
If you need to get the complete map you will need to create a big enough canvas and draw the complete map then extract the image. There is no way around (using canvas).
I'm new to HTML5 and JavaScript, and I'm trying to use the canvas element to create a high(ish) quality output image.
The current purpose is to allow users to all their own images (jpeg, png, svg). this works like a charm. however when I render the image it's always a 32-bit png. how can I create a higher quality picture using JavaScript(preferably) ?
when I output the file, it always seems to keep the same resolution as the canvas, how can I change this using JavaScript(preferably)
Thanks in Advance guys, I looked around for a while but I couldn't find the answer to this :(
If you want to create a larger image with getImageData or toDataURL then you have to:
Create an in-memory canvas that is larger than your normal canvas
Redraw your entire scene onto your in-memory canvas. You will probably want to call ctx.scale(theScale, theScale) on your in-memory context in order to scale your images, but this heavily depends on how they were created in the first place (images? Canvas paths?)
Call getImageData or toDataURL on the in-memory canvas and not your
normal canvas
By in-memory canvas I mean:
var inMem = document.createElement('canvas');
// The larger size
inMem.width = blah;
inMem.height = blah;
Well firstly, when you draw the image to the canvas it's not a png quite yet, it's a simple raw bitmap where the canvas API works on as you call it's methods, then it's converted to a png in order for the browser to display it, and that's what you get when you use toDataURL. When using toDataURL you're able to choose which image format you want the output to be, I think jpeg and bmp are supported along with png. (Don't think of it as a png converted to another format, cause it's not)
And I don't know what exactly do you mean by higher quality by adding more bits to a pixel, you see 32 bits are enough for all RGBA channels to have a true color 8 bits depth giving you way more colors than the human eye can see at once. I know depending on the lighting and angle in which the user is exposed to your picture his perception of the colors may vary but not the quality of it which I'd say only depends on the resolution it has. Anyway the canvas was not designed to work with those deeper colors and honestly that much color information isn't even necessary on any kind of scene you could render on the canvas, that's only relevant for high definition movies and games made by big studios, also, even if you could use deep colors on the canvas it would really depend on the support of the user's videocard and screen which I think the majority of people doesn't have.
If you wish to add information not directly concerned to the color of each pixel but maybe on potencial transformations they could have you better create your own type capable of carrying the imageData acceptable by the canvas API, keeping it's 32-bit format, and the additional information on a corresponding array.
And yes, the output image has the same resolution as the canvas do but there are a couple of ways provided for you to resize your final composition. Just do as Simon Sarris said, create an offscreen canvas which resolution is the final resolution you want your image to be, then, you can either:
Resize the raster image by calling drawImage while providing the toDataURL generated image making use of the resizing parameters
Redraw your scene there, as Simon said, which will reduce quality loss if your composition contains shapes created through the canvas API and not only image files put together
In case you know the final resolution you want it to be beforehand then just set the width and height of the canvas to it, but the CSS width and height can be set differently in order for your canvas to fit in your webpage as you wish.
I am searching for a 2D physics engine to simulate gravity using images, preferably PNG images with transparency. So the engine will know how to calculate the collision base on the opaque parts of the image. I have only found Javascript engines that works with primitive shapes and basic HTML elements, but not with images.
I don't know any way to do what you desire, but you can try drawing your shapes in HTML5 Canvas and use Box2D.js for working with shape collision.
One think you could do is compute the convex hull of your image (you can have a look here) and then use those hulls to compute collisions and so on (using GJK for example, you can find some great explanations here or here)
As noted by micnic, I guess you can indeed use Box2D.js and feed a b2PolygonShape why the non transparent pixels of your images (or you can compute their contours and use contours as input for the b2PolygonShape)