HTML5 Image quality after scaling bitmap is bad - html

I am creating my first game in HTML 5 for mobile.
I'm just using the library "Easeljs-0.7.0", nothing PhoneGap.
I made my images to canvas 2024x1024 pixels, then each image by setting the scaleX and scaleY. However when the scale is less than 0.5 makes all images with poor quality.
How to solve this?
var test = new createjs.Bitmap("test.png");
test.scaleX = 0.23456;
test.scaleY = 0.23456;
APP.stage.addChild(test);
APP.stage.update();

Unfortunately this is how Canvas renders the bitmap, and its not something that can be controlled by JavaScript. It is possible to get some results in various browsers using the `context.imageSmoothingEnabled' property, but currently it requires vendor prefixes. Check out this thread:
Canvas Image Smoothing
To do this with EaselJS, you need to get the canvas context, which is not currently available without manually accessing it:
var context = myStage.canvas.getContext("2d");
context.webkitImageSmoothingEnabled = context.mozImageSmoothingEnabled = true;

Related

How do I keep the AS3 Camera class from adding black bars?

Under certain conditions, picking a resolution with Camera.setMode() adds black bars to the camera input, "letterboxing" it. I understand that setMode() uses some kind of hidden algorithm that picks a resolution from one of your camera's available resolutions and then crops it to fit your desired dimensions, but apparently sometimes it would rather add black bars than crop it.
This behavior is dependent on what camera I'm using. Some cameras seem to always crop and never letterbox. This may be related to what available resolutions they have. But what's really strange is that the letterboxing only ever happens when I try it in a Flash Player ActiveX control, like in Internet Explorer. It doesn't happen when I try the exact same SWF in Flash Player Projector or Google Chrome. This seems to imply that different Flash Player versions use a different algorithm to select and fit a resolution to the desired dimensions.
Here's a very simple example of code that's been creating this problem for me. In this case I'm providing a 4x3 resolution to setMode(), which means it must be selecting a 16x9 resolution even though 640x480 is one of the camera's available resolutions.
public class Flashcam extends Sprite
{
private var _camera:Camera = Camera.getCamera("0");
public var _video:Video;
private var _width:int = 640;
private var _height:int = 480;
public function Flashcam()
{
_camera.setMode(_width, _height, 15);
_video = new Video(_camera.width, _camera.height);
addChild(_video);
_video.attachCamera(_camera);
}
}
Is there any way to stop Camera from letterboxing its input? If not, is there some way to tell whether or not it's being letterboxed and which camera resolution has been automatically selected so that I can write my own code to account for it?

AS3 AIR: loading time when adding large bitmaps to stage

I'm building a simple eBook for tablets in Flash Pro. All the pages are images (Bitmaps in library) and there's about 80 of them. To maintain good quality for large tablets, bitmaps are quite big (3999x2999).
This eBook has vertical and horizontal scrolling and these are working fine, but; due to huge amount and size of these images, I can't add all of them to stage when app starts, so I ended up adding only the closest pages to current page always after scrolling tween.
This works ok, but causes always a delay after page scroll (even several seconds with older tablet, and with new iMac it's almost 1s, so it's notable). This is basicly what I do per image/page:
var bitmapdata:BitmapData = new bitmapArray[i](); //linkage name
var hRatio:Number = stage.stageHeight / bitmapdata.height;
var bitmap:Bitmap = BitmapScaled(bitmapdata, bitmapdata.width * hRatio, bitmapData.height * hRatio);
target.addChild(bitmap); //target is a MovieClip (I have one Mc for each vertical pile of pages)
And BitmapScaled function:
function BitmapScaled(source0:BitmapData, width0:Number, height0:Number):Bitmap{
var mat:Matrix = new Matrix();
mat.scale(width0/source0.width, height0/source0.height);
var bmpd_draw:BitmapData = new BitmapData(width0,height0,false);
bmpd_draw.drawWithQuality(source0,mat,null,null,null,true,StageQuality.BEST);
return new Bitmap(bmpd_draw);
}
Also, after scrolling I clean up the ones that aren't next to new current page:
function clear(targetArray:Array):void{
for(var i:int = 0; i<targetArray.length; i++){
targetArray[i].bitmapData.dispose();
targetArray[i].bitmapData = null;
targetArray[i].parent.removeChild(targetArray[i]);
targetArray[i] = null;
}
if(targetArrays[targetArrays.indexOf(targetArray)] = new Array();
}
How often:
After horizontal scroll I add one new horizontal page and one new vertical page, and remove one horizontal and at least one vertical page.
After vertical scroll I add only one new vertical page (if next vertical page is one that I already haven't added), so vertical pages I keep in stage untill next horizontal scroll happens. This takes a smaller delay, but also notable.
I know Flash/AIR is not the best way for this, but it's all I have now. How could I get rid of the addChild-delay? Yeah you can't, so any better ways to do all this?
I'm pretty sure I'm using the hard way with something here, but just can't figure out what and how I should do it.
BitmapData drawing on mobile device is too slow to be used on the fly, if you must use it do your drawing on app start (still slow though). BitmapData blitting is a little bit faster but still too slow to be used on mobile device.
With large amount of assets like in your case, Stage3D frameworks like Starling might not be the best solution either as texture uploading is also slow and limited in memory amount (when limit is reached the app crashes).
Best might just be to copy what typical Android/Ios development use: Few different resolutions for all assets with a minimum of 1x and 2x.
I personally use 0.5x, 1x, 2x, 3x and developed a framework that switches resolution according to different settings (very much like XCode does). But still you can keep things simple without a framework and just set at app start the asset resolution you'll use for the app. I would also make sure to remove and add those assets on screen as they are needed.
don't use that "new BitmapData" in conjunction with the "dispose". when you load your bytes load it directly into the already existing bitmaps on the stage. try to have as little modification of the allocated memory as possible through your load-resize-display pipe.
removing and dumping pixels onto the renderer is far slower than changing already existing ones.

Issue while loading big images inside svg on FabricJs

We are using a FabricJS editor and we are loading SVG templates into it. We are also editing some texts, changing positions of objects and saving as SVG. Everything works fine here.
But now we need to load very big images inside one SVG. Each images in the SVG is going to be high resolution as this is used for print industry. Here we are not able to load that SVGs as the embedded images are very bigger.
We thought of a solution of re-sizing those images before loading to editor and after editing bringing back the original images as output. But this also does not work out as when we resize, we are facing some issue with positioning of objects in the SVG
Can someone suggest a way to fix this issue
I have also been using fabric.js for the same reason as yours.
As the issue of positioning image while showing on the canvas. You can position it like this.
$('#canvas').attr('width',img_data.width).attr('height',img_data.height);
var canvas = new fabric.Canvas('canvas');
var imgElement = document.getElementById('myimg');
var CanImg = new fabric.Image(imgElement, {
left: -1 * img_data.x,
top : -1 * img_data.y,
});
CanImg.selectable = false;
canvas.add(CanImg);
Using Left and top you can set position of x and y co-ordinates of the image.
It will work on the large image too.
You might get stuck at showing large image on canvas. But as far as the issue of positioning image, this will work.
Good Luck.

Rendering not working with MediaElement windows RT

I need to take thumbnail from Video playing with MediaElement
For this i learn there is RenderTargetBitmap in windows 8.1 API
RenderTargetBitmap a = new RenderTargetBitmap();
await a.RenderAsync(myMedia);
thumb.Source = a;
and second way i got with help of WinRTXamlToolkit.Composition toolkit which do rendring with WriteableBitmapRenderExtensions class
WriteableBitmap w = await WriteableBitmapRenderExtensions.Render(myMedia);
thumb.Source = w;
Both these methods are working with all UIElement but not with MediaElement
only black screen is visible when source this to Image object.
Can any one tell me why? and how can i take thumbnail from video?
It seems like the methods you mentioned might be limited in that regard. I'd still try RenderTargetBitmap but with something overlaid on top of the MediaElement. I believe if you place anything on top of a MediaElement, like a 0.01 opacity, 1x1 sized, black rectangle - it will switch to run in some different rendering mode where it is possible RenderTargetBitmap would be able to render it. Otherwise I think someone discussed here a while back a question of capturing a frame from a video stream. IIRC it is a pretty involved process though, involving using DirectX or Media Foundation and quite a bit of native code.

AS3 Camera input gets distorted when exported to AIR

I've built an AIR application with flash/as3 that has a webcam display on the stage. While building the app, and in all my tests everything looks and works just dandy, but when I publish for AIR the image gets stretched. The bounds of the image seem to stay the same, but the actual cam output is what's distorted. Has anyone come into this problem before?
I should add, this is a desktop app, which is permanently installed on one machine, so device compatibility should not be an issue.
this is the camera setup:
var cam:Camera = Camera.getCamera();
cam.setMode(280,380,20);
var video:Video = new Video(380,380);
this is where i first call the camera...
video.attachCamera(cam);
video.x = 355;
video.scaleX = -1;
video.y = -100;
addChildAt(video, 0);
the reason for the odd sizing, is that it sits behind a frame, that changes positions throughout the interactive.
Not necessarily the answer you are looking for, but you should keep this in mind:
You are asking the camera to capture at the resolution of 280 x 380, which is not a standard 4:3 aspect ratio.
When you call cam.setMode(280,380,20); the docs say that Flash will try to set the cameras resolution to your specifications, and if the camera does not support that resolution it will try to find one that matches. So you may or may not be getting this actual resolution.
setMode() has a fourth parameter, which can disable this functionality. Read the docs on that so you understand the implications :)
Then you display the video in a Video object that is 380x380. So I would expect the image to be stretched in the horizontal direction (b/c the original source is only 280).
It's not clear why this behaves differently: are you saying that running the debug version of the app works, but when you export the release build and run that it looks funky?
Finally, what is scaleX = -1 doing? I recall this as some sort of nifty trick I used in the past... but it's purpose here is escaping me :)
Yep, source code would be cool. Btw, i suggest you, as soon as you get the video streaming running, to set by hand the video.width and video.height property.
This will force the cam to display at the correct size.