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
}
Related
I have a React app that displays a series of images. Recently I've begun to notice that some images which are snapped as portrait are displaying on UI as rotated by 90 degrees. I've eliminate all of the css stylings in an effort to figure out why this is happening, however removing all of them hasn't changed the orientation at all.
This has led me to conclude that its the browser (Chrome) that is making the determination of orientation. One thing noticed is that browser shows the NaturalHeight and NaturalWidth values for the rotated images as reversed from what is expected. For example, if a certain image is viewed using Gimp the exif ImageLength x ImageWidth shows as 3088x2320 which is correct for a portrait image. However - interrogating the same image in the app via the browser reports NaturalHeight x NaturalWidth as 2320x3088, which is reversed.
So questions are:
1) why the reversal? and
2) is there anything that can be done about this?
Thanks
I am using fabric.js.
I am loading a background image into canvas and the image is not streching.
If i upload just the image everything is good, when i add filters to background image, the background image not stretching to full width of the canvas.
I tried to add filters after loading the image.
Tried also remove background and load again, everything is going to the same place... Image not stretching.
This is a fiddle with only background image:
`https://jsfiddle.net/Music/6mcf4kj0/2/`
This is a fiddle with background image and filters:
`https://jsfiddle.net/Music/q30cfwL7/1/`
I expect the image to be full width and height of the canvas.
Your image is 3000x3000, which is too large for the default fabric.js settings. From the filter docs:
The picture will be painted over a tile of 2048x2048 size, bigger
pictures won't fit. fabric.textureSize set at 2408 is a safe limit.
Most of the hardware will support 4096 and so 4096x4096 is a limit
that will probably work and give you less headaches. Take in mind that
canvas has a max size too. If you are supporting browsers like IE11
you will have probably problems with canvases bigger than 5000 on a
size, whatever your webgl hardware is capable of.
Try this before applying the filter:
fabric.textureSize = 4096
You can also check if Webgl is supported then apply
if (fabric.isWebglSupported()) fabric.textureSize = 65536;
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.
I am trying to load a HTML file that does one thing: display an image on a canvas element that is auto-resized and auto-rescaled to the maximum dimensions for the device in question.
For example:
User presses button on device.
Device opens WebKit/WebView to http://some.url/page.html.
That page shows image.png in the maximum height/width proportion possible on said device.
Requirements:
Actual HTML file should only contain a canvas element within the body.
Image path should be dynamic and the width/height interpreted after the file has been loaded.
No third party dependencies.
I took a stab at this here, but am running into problems: http://jsfiddle.net/zfG2B/
if (scaledHeight < scaledWidth) {
_config.newImgHeight = _cache.canvas.height;
_config.newImgWidth = Math.round(_config.newImgHeight * _config.imgWidthRatio);
} else if (scaledWidth < scaledHeight) {
_config.newImgWidth = _cache.canvas.width;
_config.newImgHeight = Math.round(_config.newImgWidth * _config.imgHeightRatio);
}
The code I've cobbled together (above, and see jsfiddle) kind of works, but I can only get it to rescale based on the height. Any ideas on what I've done wrong or the best path forward?
For reference, I've attempted to join together the best of:
HTML5 Canvas Resize (Downscale) Image High Quality?
Scaling HTML5 canvas width preserving w/h aspect ratio
Resizing an image in an HTML5 canvas
HTML5 Canvas drawImage ratio bug iOS
scaling a canvas element and keeping the aspect ratio
So here's the question: what's the best way to place an Image on a Canvas in HTML5 and make it auto-rescale based on the current screen size? Bonus points for being able to specify a clipping range!
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.