Load large images and tile in Javascript on iPad - javascript

I want to load an image of dimensions larger than 2000x2000 pixels on the iPad to show in canvas on a webapp - e.g. 4000x4000 pixels. Due to memory limit, this doesn't work. Could it be possible to load the image into htmlstorage, tile it there, and then show only tiles in the canvas? Or is the limit of around 2000x2000 pixels absolute? I could tile on server, but it is not too easy to do for the current application.
There are some discussion about loading several images which are more than 6 MB in total (e.g. iPad/iPhone browser crashing when loading images in Javascript ), but this does not apply to my case as I have one image which itself is over the memory limit.

I'd try splitting the image as you suggest and see if some of it can be saved to sessionStorage/localStorage. However don't forget there appears to be a 5MB limit for localStorage (Limit of localstorage on iPhone?) on iOS.

Related

How can I optimize HTML canvas and JavaScript to handle large sized images for a web-based image editor

I am building a web-based image editor, and everything seems to work fine until very large images are uploaded (>5mb), and then operations like adjusting the brightness using a slider takes a while to reflect. The issue is quite obvious, and that is because I have to loop through each pixel (step of 4) in context.getImageData().data in order to modify each pixel value.
I checked out a couple of already existing online image editors, and theirs seem to work pretty well without lags.
Initially, my first step was to resize the image to fit the canvas on the screen which worked fine without lags, but why I switched to modifying the original image size was because the original size does not change compared to the one on the screen which changes if the user resizes the screen (or if chrome displays the currently downloading bar at the bottom of the browser), and since it is constant, I can always keep track of all editing operations, and then display on the screen by basing scaling down to fit the screen.
I'd love to know how I can optimize for large-sized images, without losing the quality of the original (due to resizing etc). Thanks!
[UPDATED]
This was copied from a comment under this post.
"JavaScript is not suited for image pixels editing. That is what the GPU is for. Most image manipulation needs can be done using filters, standard 2D canvas as they use the hardware designed for the task. If you have custom PX manipulation needs then WebGL is the solution."

Uploading cropped image from multiple devices while maintaining larger image size

My goal is to allow users to upload a profile image, and to crop the image prior to uploading in order to fit nicely in the image container. This is a very common issue.
The problem I’m having is that when the user is using a mobile device, the cropped and uploaded image ends up being roughly 350 pixels wide, which results in highly pixelized images when viewed on a large screen that ends up stretching the image as needed (upwards of 700 pixels).
The flow is as follows: user chooses new image locally to upload; this image is then implanted into the browser in order to be cropped; the resulting cropped image (base64) comes out with the correct aspect ratio, but the size (width and height) in pixels is in accordance with the devices screen width, which may be very small depending on the device.
I’m using Croppie.js to do the cropping, which works fine. However, the resulting base64 image located in the browser is very small in pixels when cropped on a small device (phone, etc.). The base64 image is what ends up getting uploaded, so this results in the problem mentioned above with stretching and pixelization on larger devices.
Any input or other techniques that I’ve overlooked would be greatly appreciated.
Per https://foliotek.github.io/Croppie/ :
when you call for result, using size = original should get you the higher quality image, which you can scale to the size you need when you display it.

Is there a relationship between image dimensions and file size?

I'm creating a HTML5 upload plugin (I'll link to it when it is completed) that reads an image from the file system, and then displays the image onto a canvas. I then read the canvas data and send it up to a server for processing.
Displaying the image on a canvas smaller than the original image dimension shrinks the file size down. What I noticed was that for a canvas of dimension 1024 x 768, the file size was the same for an input file of 5MB and an input file of 100+MB (around 1.1MB), which leads me to the question I ask today!
In uncompressed form, yes - in compressed form no, not necessarily.
In compressed form content is the dominating factor as well as type of compression. The more high-frequency signal the image has (noise, details) the harder the image is to compress, so two images of the same dimension can be compressed to two different sized depending on the content.
One small image with high frequencies can become larger than a large dimension image with low frequency (blurred, noise-free etc.).
If you get an image with large size after compression you can use low-pass filtering on it (ie. here: blur it a bit).
The image dimension is directly proportional to the image size. If you are processing the image before sending it to the server and resizing it then your no doubts your image size is going to be affected.
I found that images are resized in all kind of actions, e.g. by opening a jpg file and writing it back again, by using your PC's encoder which may give a different result than the original encoder did. I am still looking for a way to prevent that! So it seems logical that using a canvas and reading the image from there also changes the file size. I assume these links may help you further:
HTML5 canvas: image resizing
Html5 Canvas resize
Dick

Mobile safari downsamples large images. How to retain?

I have an HTML page with a 1675px by 2640px image in it. I tried viewing it in an iPad and apparently mobile safari downsamples the images. We wanted to show a high quality image but safari restricts this.
I've been searching for a solution to retain the image size. I've been viewing it in iPad 3 on mobile safari. People are suggesting to use another browser but by default we are using mobile safari.
Are there any CSS, JavaScript or other solution to this restriction?
I'm sure you are just going to love this answer, but the short answer appears to be: "you aren't going to get 1:1 large sized images".
The slightly longer answer is that Apple intentionally forces things to work this way because before the way it worked was just to not load the image at all, or crash.
Now, for a fuller answer with citations...
Apple's Known Resoruces Limits
The thing is, when an image is decoded/decompressed it takes up a whole heck of a lot more RAM space than the images filesize. The formula Apple states is that devices with 512mb of RAM, like the ipad 3 you mention, will refuse non-JPEG images above 5 megapixels, which results in:
height * width <= 5 * 1024*1024
For JPEG, Apple notes they will subsample to allow you to view jpegs:
The maximum decoded image size for JPEG is 32 megapixels using subsampling.
JPEG images can be up to 32 megapixels due to subsampling, which allows JPEG images to decode to a size that has one sixteenth the number of pixels. JPEG images larger than 2 megapixels are subsampled—that is, decoded to a reduced size. JPEG subsampling allows the user to view images from the latest digital cameras.
Note that it states 2 megapixels is the limit for full-sized viewing of JPEG, which is 2*1024*1024. As your image is roughly a bit over 4 megapixels, it will be subsampled on iPad 3. And no, there really isn't anything you can do to force it without using an external program.
To use an external program for minimal improvement, see this link where a person recommends GoodReader: Apple Forum, Seeking Full Image Resolution in MiniSfari
And here is another Stackoverflow with a similar question/answer pair: Image Size Limitations in Mobile Safari
Mobile Safari does not downsample progressive JPEGs. Assuming JPEG is an acceptable format for your purposes, simply convert them to progressive encoding. Assuming you have an existing, non-progressive JPEG image, you can use a tool such as jpegtran to losslessly convert the encoding to progressive scan.
To enjoy the retina feature of iPad Retina and iPhone 4 / 5, use doubled size image as follow:
<img src="test.jpg" width="837" height="1320" />
Note the dimension is reduced to half, but the test.jpg does not require to resize.
Alternatively, you can prepare another set of high resolution graphics, and show it when retina screen is detected, using Media Queries ( Modernizr )
Pixel Density Theory: Retina screen puts 2 pixels into 1 pixel, e.g with 320px width, it actually contains 640px contents. Read more here: http://www.sitepoint.com/css-techniques-for-retina-displays/

How to prevent #2x image scaling within javascript on a retina iPad?

I'm developing a web game using html <canvas> and javascript. The game must also be functional on the iPad, preferably both retina and non-retina displays. In this game, I use a spritesheet png. This spritesheet is 3500 pixels wide and 3700 pixels high.
In the logic for my game, I'm using canvas' context.drawImage() to grab the sprites and draw them into my canvas. In a desktop browser, this works perfectly fine, and everything is great. On a retina iPad, the image loads at only a quarter of it's size, which makes many of my drawImage() calls fail, thinking they're trying to grab pixels outside the boundaries of the loaded image. (If I grab a sprite at location 1200, 1400, and the iPad thinks my image is smaller than that, an INDEX_SIZE_ERR error is thrown.)
For example, the code written below is what I have in my project. When alerting the width and the height, I get a result of 875 pixels wide by 925 pixels high - exactly 1/4th of the original image's size.
spritesheet = new Image();
spritesheet.onload = function() {
splashInterval = setInterval(renderFrame, 30);
alert(spritesheet.width); // returns 875 on retina iPad
alert(spritesheet.height); // returns 925 on retina iPad
};
spritesheet.src = "/spritesheet.png";
The normal solution to this for retina displays is to create an image that's increased in size so when the iPad downscales it, everything is fine. However, going by the sizes reported above, I would have to create an image that is 4x the size in width and height. That makes an image that would be 14,000 pixels wide by 14,800 pixels high. Even as a solid white jpg, this image fails to save in Photoshop, and is reported in Gimp to be 1.9GB big. Naturally this isn't a solution. ;)
Therefore my question stands: Is there a way to prevent the iPad retina display from downscaling images that are loaded through Javascript? When I load my 3500x3700 pixel image, I need it to stay at 3500x3700 pixels, so my context.drawImage() calls work as intended.
Any and all ideas would be appreciated. Thanks!
you can find whether the display is retinal or not using following :
var retina = window.devicePixelRatio > 1 ? true : false;
if (retina) {
// the user has a retina display
// do something
}
else {
// the user has a non-retina display
// do something else
}

Categories

Resources