canvg toDataURL not returning full image with large chart - canvg

I have chart with 4000 x 10000(+).
While converting the image it is returning 4000 x 8000 image which is not full image.
Code : var canvas = document.createElement('canvas');
canvg(canvas, this.canvas.toSVG()); // this : rapheal object
var img = canvas.toDataURL('image/jpeg');

The max resolution supports 8192 px. So solve this problem by compress the image to max height of 8192 px if the height is more than that using scaleHeight property.
var maxChartHeight = 8192;
canvgOpt.scaleHeight = Math.min( canvas.height, maxChartHeight );
canvg( chartCanvas, canvas.toSVG(), canvgOpt );

Related

Pixi.js - Unable to set sprite width to full width of canvas

Ultimately I want to have a canvas that fills the entire viewport width of the browser and have an image on the canvas fill the entire width of that canvas. I'm taking advantage of pixi.js's displacement filter so that I can create a pseudo 3d effect using a depth map underneath it. The code I'm currently using is
let app = new PIXI.Application();
var w = window.innerWidth;
var h = w / ratio;
app.view.style.width = w + 'px';
app.view.style.height = h + 'px';
document.body.appendChild(app.view);
let img = new PIXI.Sprite.from("images/horses.png");
img.width = w;
img.height = h;
app.stage.addChild(img);
depthMap = new PIXI.Sprite.from("images/horses-depth.png");
depthMap.renderable = false;
depthMap.width = img.width;
depthMap.height = img.height;
img.addChild(depthMap);
app.stage.addChild(depthMap);
displacementFilter = new PIXI.filters.DisplacementFilter(depthMap, 0);
app.stage.filters = [displacementFilter];
Here's a screenshot of it in action.
I even tried manually setting the width to the viewport pixel width on the canvas and the sprite to the actual pixel width of the viewport width and it still wasn't the right size. Manually setting the width for the viewport and sprite to the exact same number also doesn't work; the sprite is inexplicably smaller than the canvas.
I tried to look at the documentation of the sprite class and see if there is something unusual about how sprites handle widths but I couldn't find anything https://pixijs.download/dev/docs/PIXI.Sprite.html
How can I create a pixi.js sprite that fills the entire width of the canvas in order to make both the canvas and the sprite fill the entire viewport width?
pixijs.download
PixiJS API Documentation
Documentation for PixiJS library

Canvas content disappering on resize [duplicate]

This question already has answers here:
Resize HTML5 canvas element
(3 answers)
Closed 8 years ago.
Probably I'm missing something fundamental.
I'm filling a canvas with objects. On user input I need to resize the canvas (thus scaling the content).
JS (simplified):
var c = document.getElementById('c');
var cc = c.getContext('2d');
cc.beginPath();
cc.rect(20, 20, 20, 12);
cc.fill();
function resizeCanvas(size){
var c = document.getElementById('c');
var cc = c.getContext('2d');
// This will make the content disappear
c.width = c.style.width = c.height = c.style.height = size;
}
HTML
<canvas id="c" width="200" height="200"></canvas>
<br/>
<button onclick='resizeCanvas(100);return false;'>Resize</button>
CSS
canvas {border: 1px solid black}
The canvas is resized but the content is blanked. Any idea?
jsfddle here
By changing either width or height -and obviously by changing both-, you completely redefine the canvas, so in fact it is quite logical that the canvas content is cleared : how should it change ?
Should it scale ? , re-use existing pixels values, but how ? centered, ... ??
That was even a 'trick' at some time : to clear a canvas, just do canvas.width = 0 then canvas.width = oldWidth , and that will clear things up. Since clearRect or fillRect are now faster that this trick, it has no reason to be used any more.
So when your canvas get resized, it will get cleared. It's up to you to decide of the policy you want when such resize occur : will you scale old canvas and copy it on the new one, or copy at same scale centered, or will that be an up/left most copy ??
you decide.
If you have a 'scene graph', meaning : if you are able to redraw every objects of your canvas, there's no real issue.
If you don't, you have to do some efforts to get the old content on the new canvas.
Something like (untested) :
function resizeCanvas(size){
var c = document.getElementById('c');
var canvasCopy = document.createElement('canvas');
canvasCopy.width = c.width; canvasCopy.height = c.height;
canvasCopy.getContext('2d').drawImage(c, 0,0 ); // copy the 'old' canvas
// This will make the content disappear
c.width = c.style.width = c.height = c.style.height = size;
var cc = c.getContext('2d');
cc.drawImage(canvasCopy, 0, 0) ; // or you might scale, or center, or...
}

Canvas reduces imagesize of Jpeg, but why?

When I draw a JPEG-Image to Canvas using drawImage() and after that, using canvas.toDataURL() to make it saveable local (with right mouseclick), then the saved Jpeg-Image has a reduced filesize about 40%. It is only so, when using Jpeg. PNG, GIF (NON-COMPRESSION-FILES) rises up the size. I thought, if I convert a Image-File to Base64 the size grows up to about 130%. So I think the canvas-element has an own integrated compression-functionality? If so, can I deactivate it?
The Code looks like this:
var img = new Image();
img.onload = function ()
{
var width = img.width;
var height = img.height;
context.drawImage(img, 0, 0,width,height);
document.images[0].src = canvas.toDataURL('image/jpeg');//<-size = 30,2 KB (30.990 Bytes)
}
img.src = "http://www.roomeffect.de/pageslices/RSB.jpg"; //<-original file size = 58,5 KB (59.930 Bytes)
I don't know what the problem is?
You can specify the JPEG quality as the second parameter to the toDataURL function. The default quality in Firefox is 0.92 (92%).
https://developer.mozilla.org/en/DOM/HTMLCanvasElement
It's not a problem. JPG is a lossy format, there's no reason to expect a JPG which is expanded into a bitmap (so you can see it on the screen) to be the same size as a new JPG made from compressing that bitmap again. If you want the original file to be saved, save the original file.
This should give you the best results:
document.images[0].src = canvas.toDataURL('image/jpeg', 1);
Quoted from MDN:
If the requested type is image/jpeg or image/webp, then the second
argument, if it is between 0.0 and 1.0, is treated as indicating image
quality.

AIR - set size of NativeWindow to include system chrome

How do you find out the size of the system chrome so that I can specify the window size to achieve the stage size I want?
If my main window is set at 800 x 600 (stage), and I create a second window as below, it will be smaller.
public function Main():void
{
var windowOptions:NativeWindowInitOptions = new NativeWindowInitOptions();
windowOptions.systemChrome = NativeWindowSystemChrome.STANDARD;
windowOptions.type = NativeWindowType.NORMAL;
var newWindow:NativeWindow = new NativeWindow( windowOptions );
newWindow.width = 800;
newWindow.height = 600;
newWindow.stage.scaleMode = StageScaleMode.NO_SCALE;
newWindow.stage.align = StageAlign.TOP_LEFT;
newWindow.activate();
}
I assume you increase both newWindow.width = 800; and newWindow.height = 600;to account for the chrome, but how do you find this value?
you can calculate the size of the chrome by substracting the windows size (that include the chrome) with the inner size (that exclude the chrome).
From the width help of NativeWindows :
The dimensions reported for a native window include any system window
chrome that is displayed. The width of the usable display area inside
a window is available from the Stage.stageWidth property.
So the inner size can be obtained with stage object ( stage.stageWidth and stage.stageHeight: )
hence :
var chromeWidth=newWindow.width-newWindow.stage.stageWidth;
var chromeHeight=newWindow.height-newWindow.stage.stageHeight;
When creating ActionScript projects with NO_SCALE the stage.stageHeight and stage.stageWidth cannot be used to calculate chrome in the main application window as they do not resize to conform to the inner width. You must reference the main window stage.
To find the main windows inner stage height and width you can use the stage.nativeWindow.stage references stageHeight and stageWidth properties which gives inner width.
e.g. for a 1280x720 desired inner size:
// width stage.nativeWindow.width = 1280 + (stage.nativeWindow.width -
stage.nativeWindow.stage.stageWidth);
// height stage.nativeWindow.height = 720 + (stage.nativeWindow.height
- stage.nativeWindow.stage.stageHeight);
For reference, as I feel the other answers aren't clear enough. To set a new window to the desired dimensions:
// first set the desired window dimensions to set the (smaller) stage dimensions:
newWindow.width = 1024;
newWindow.height = 768;
// then reset the window dimensions and add chrome dimensions:
newWindow.width = 1024 + (1024 - newWindow.stage.stageWidth);
newWindow.height = 768 + (768 - newWindow.stage.stageHeight);

Scaling and cropping an image with fixed dimensions

I want to display an image, and it should be transformed like this:
If for example, my original image is 200x300 pixels in size, I want it to have a width of 150, and then scale the height accordingly. Then I want to crop the image, so that the result has a dimension of 150x150 pixels.
I've tried several ways, but haven't figured out how to do it.
You can calculate the scale factor by dividing new width by old width:
var scale : Number = 150 / myImage.width;
myImage.scaleX = myImage.scaleY = scale;
To crop, either use a mask on the scaled clip, or draw to a new Bitmap:
var myBitmapData : BitmapData = new BitmapData ( 150, 150 );
// use concatenated matrix of the image to scale the new bitmap data
var matrix : Matrix = myImage.transform.concatenatedMatrix;
myBitmapData.draw ( myImage, matrix );
var myBitmap : Bitmap = new Bitmap ( myBitmapData );
addChild ( myBitmap );
Depending on how many images there are, and what you are going to do with them later, you should always test both possibilities for performance.