Canvas drawImage with large images - javascript

What I am trying to make is some kind of scrollable viewport in which a really large image is loaded (as in 10.000 x 10.000 pixels or more) and I should be able to draw some lines / shapes on this image.
There are two methods I can think of to draw the image / allowing the shapes to be drawn:
Using an tag to draw the image and draw a canvas the size of the image above it.
Using the drawImage() method to draw the image and just use a canvas.
I have tried both cases but when I load an image (in the img tag or using the javascript Image() object) it consumes about 500MB of memory.
I am wondering if there is a more efficient way to accomplish this.

Never ever make a user download an image that size unless you absolutely have to.
Make 100 smaller tiles (or thereabouts) of the image and draw the tiles to the Canvas, only drawing the tiles that can be seen at the current time (like google maps, etc do).

Related

How to crop HTMLVideoElement in WebGL's texImage2D?

I'm playing around with WebGL, and I can successfully render a video element to a WebGL context with texImage2D. However, I'm now trying to crop this video element before rendering it. For example, I want to take the top half of the video element and draw it in the left half of my GL context; and the bottom half in the right half.
What is the best practice for this "crop action" in WebGL 1?
I have figured out that I can adjust the viewport to render something in the left/right half, but I can't seem to find how to crop.
It would be nice if texImage2D supported offset and dimension parameters for video elements, but that's not the case.
Maybe I can adjust this in the texture parameters or something?
In WebGL1 there is no easy way to crop at the texImage2D level. I suggest you just put the entire video frame into 1 texture and then use texture coordinates when rendering to select the part of the texture you want to display in each area

toDataURL() small screens, small saved image

I have created a web application which uses an HTML5 canvas element to allow users to draw in various shapes, colors, line widths. They can also upload an image, have it drawn onto the canvas and then draw on top of that, as a way to annotate their images.
My challenge is that I am using .toDataURL() to get the entire contents of the canvas saved as an image. As I understand, though, this can only capture the size of the canvas. On smaller devices (phones), the image which is saved, ends up quite small dimensions. Here's what I am doing to get what is on the canvas:
var image = document.getElementById("drawingCanvas").toDataURL("image/jpeg", 1.0);
image = image.replace('data:image/jpeg;base64,', '').replace('data:image/png;base64,', '');
Is there some way to set up my canvas to be able to save larger images, even if the size of the canvas is quite small, due to the device?
Sure...
Save the commands used to create the client's drawing.
Create a larger in-memory canvas with document.createElement.
drawImage a full-sized image to the canvas.
context.scale the canvas.
Re-issue the drawing commands.
Export the enlarged canvas with .toDataURL.
Thanks to context.scale you don't have to change any of the coordinates of the drawing commands.
...and alternatively...
You could eliminate step#1 if you're willing to downgrade the drawings to allow some "jaggies". Do this by using CSS to overlay a canvas on top of the client's img. That way the client's drawings are already isolated on the original canvas. Then your procedure simplifies to:
Create a larger in-memory canvas with document.createElement. Make sure the larger canvas has the same aspect ratio as the original canvas.
drawImage a full-sized image to the canvas.
drawImage the original smaller canvas to the larger canvas. You can use the extended version of drawImage to simultaneously scale the client's drawings: context.drawImage(originalCanvas, 0, 0, originalCanvas.width, originalCanvas.height, 0, 0, largerCanvas.width, largerCanvas.height). Yes, the image source for drawImage can be another canvas. ;-)
Export the enlarged canvas with .toDataURL.

Add background pattern to a png image in canvas

As the title says, i want to add background pattern to a png image(not the whole canvas). I tried various guides but they are all about adding background pattern to whole canvas by either using background-image css property or by using canvas's createPattern method.
This is what i'm creating.
As you can see, there are various png images on the canvas(left arm, right arm, body, etc.) and they are all customizable. Now i want to add repeat-pattern to those png images. Those repeat pattern would be an image itself.
How to do that via svg, fabric or any other method?
A really simple way is to create a FOR loop to draw your PNG images at the size you need.
Use the canvas width/height values,your image size and your preferred image distance to determine
the number of iterations your loop needs to run.
On each iteration increment a distance variable a certain value in
order to blit your image at an increasing distance on the x/y axis.
When the loop ends you will have a pattern.

kineticJS createImageHitRegion for sprites, not images

I am using KineticJS and wish to create a precise image hit region (ignore transparent pixels) for my sprites. I see how createImageHitRegion accomplishes this for images, but I don't see how to apply this to sprites. Said another way, while method createImageHitRegion is a method which accomplishes what I want for images, there appears no similar method for sprites. If I could create an image hit region on just one image of each of my sprite that could work for me, but a big rectangular region which encompasses the entire width and height of the image of the sprite can't work. Any ideas for a workaround? Perhaps I've missed something?
There's no easy way hit-test non-transparent pixels on sprites.
I can think of a couple of theoretical workarounds...
If you can draw a path outlining the pixels you want to hit.
The sprite object allows a custom drawHitFunc so you could use mySprite.afterFrame to redefine a custom hit area for each of your sprite images.
mySprite.afterFrame(0, function() {
mySprite.setDrawHitFunc(function(){
// draw the path you want used for frame#0
});
});
// repeat for all frames
If you can't draw a path outlining the pixels you want to hit.
Instead of using sprites, make your own sprites using individual images.
Do that by creating a series of images (including createImageHitRegion) and sequentially making one of those images visible so it appears to be playing a spritesheet.

Stretching/distorting a background image from a single point

Usually when an image is being resized in javascript or css3(using background-size), it will stretch an image from the center point. I need an image to be stretched and distorted from a single point that could be anywhere. It's going to be dynamic so I don't want to resort to using separate images.
Here's a pic that illustrates what I mean:
Hopefully there's an answer out there!
You have a few options to achieve this effect.
The "correct" way would be to use canvas to draw the image: Skewing images individually using canvas
Another way would be to fake the effect using the CSS transform skew.
http://developerdrive.com/demo/skewing_elements/skewing_elements.html
You would do this inside an element with "overflow: hidden" to make it look like a background image.
It's not even clear to me what you want from the image you're linking too. Do you want it distorted or not? And is the distortion uniform?
I'm going to guess whatever you're doing can be approximated by drawing an ever decreasing set of (or maybe rectangles) clipped from the center of a some image and drawing them onto a "canvas" (think generic term not html5 term) given new coordinates for the center of each clipping. There may be a faster way to draw this than redrawing parts of the image multiple times, it's just how I visualize it possibly working.. at least maybe in some mathematical sense.

Categories

Resources