How to get Aspect Ratio of device in Cocos2d-x? - cocos2d-x

Is there any way to get the aspect ratio of device. For example whether it is 16:9 or 4:3 or 3:2?
I want to exact fit resources for these resolutions. The problem i face is device dont give the exact values for example width/ height of iPhone 4inch is not exactly 16:9 but relatively equal. Is there any way to get the devices aspect ratio?
thanks in advance

This is pseudo code to get aspect-ratio of the screen. You might need to set table has 16:9, 4:3, 3:2, or whatever you want aspect-ratio entries.
auto frameSize = Director::getInstance()->getOpenGLView()->getFrameSize();
auto aspectRatio = frameSize.width / frameSize.height;
int aspectRatioType = DEFAULT_ASPECT_RATIO_TYPE;
float closest = FLT_MAX;
for (const auto& i : table) {
auto d = fabs(i.aspectRatio - aspectRatio);
if (d < closest) {
closest = d;
aspectRatioType = i.aspectRatioType;
}
}
return aspectRatioType;

Related

Fit (contain) <img> of unknown size to parent, keeping aspect ratio WITHOUT img-element having same w/h as parent [duplicate]

I realise this has been asked many times under many guises, but most solutions seem to not care about the resulting image height, or only scale in one direction. This:
min-width: 100%;
height: auto;
isn't a solution.
I'm trying to fit an image to the height and width so that it can be dynamically injected into a number of places in different systems and sites, so I don't necessarily know what the parent object is going to be - might be a div with or without overflow set, or a p, or the body - or its dimensions; The parent container mustn't change size just by injecting my image/script .. jQuery is NOT available.
I can't see how the css3 background technique would work.
Proportional scaling is as easy as using a ratio:
<img onload="scale(this)" src="screenshot.png">
<script type="text/javascript">
function scale(img){
var p = img.parentNode,
x = p.offsetWidth,
y = p.offsetHeight,
w = img.naturalWidth,
h = img.naturalHeight;
ratio = h / w;
if (h >= y) {
h = y;
w = h / ratio;
img.style.width = w + "px";
img.style.height = h + "px";
} else if(w >= x) { //} && ratio <= 1){
w = x;
h = w * ratio;
img.style.width = w + "px";
img.style.height = h + "px";
}
}
</script>
but this only scales in one plane - I need it to continue to scale both width and height until it fits into the parent container space neatly in both dimensions. If the image is smaller than the parent container, it should scale UP to fill proportionally.
Adapt image to fit parent container (of unknown size) without stretching image
Instead of messing with JS, let CSS do the job!
Set your image to 100%; height and width;
Replace your image's src with a transparent pixel and set it's background to the actual src.
Use CSS's background-size on your (now) full-sized image:
contain (image will cover the parent completely)
cover (image will respect image proportions instead)
Example using contain
function scale( img ) {
if(img.isScaled) return;
img.style.background="no-repeat url("+ img.src +") 50%";
img.style.backgroundSize="contain"; // Use "contain", "cover" or a % value
img.style.width="100%";
img.style.height="100%";
img.isScaled=true; // Prevent triggering another onload on src change
img.src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
}
<div style="width:300px; height:300px; background:#000; margin:10px;">
<img onload="scale(this);" src="//placehold.it/1200x600/f0f">
</div>
<div style="width:300px; height:300px; background:#000; margin:10px;">
<img onload="scale(this);" src="//placehold.it/400x600/cf5">
</div>
Tested in: FF, CH, E, IE(11), SA
NB: The transparent pixel data is used solely to prevent the browser's Missing Iimage Icon that would be otherwise caused by doing img.src = "";
http://caniuse.com/#search=background-size
I used this code to fit a video to its parent:
var parent = vid.parentNode,
vw = vid.videoWidth,
vh = vid.videoHeight,
vr = vh / vw, // video ratio
pw = parent.offsetWidth,
ph = parent.offsetHeight,
pr = ph / pw; // parent ratio
if(pr > vr) {
vid.style.width = 'unset';
vid.style.height = `${ph}px`;
} else {
vid.style.height = 'unset';
vid.style.width = `${pw}px`;
}

`Autodesk.Viewing.ScreenShot.getScreenShotWithBounds` uses viewer's default camera dimensions instead of bounds

Following this advice I am trying to replace our usage of viewer::getScreenshot with Autodesk.Viewing.ScreenShot.getScreenShotWithBounds which calls Autodesk.Viewing.ScreenShot.getScreenShot to support larger screenshots. However, the bounds are ignored. The behaviour seems to be that it makes a screenshot of the viewer's default camera or corresponding to its dimensions. Then it stretches the image to fit the given width and height. I expected the function to return a screenshot of the elements inside the given bounding box.
Is the function getScreenShotWithBounds supposed to do something different from what I am assuming?
Example code (LMV 7.40.0):
const bbounds: THREE.Bbox3; // calculated for some elements I want to screenshot
Autodesk.Viewing.ScreenShot.getScreenShotWithBounds(NOP_VIEWER, Math.ceil(bbounds.size().x * 4), Math.ceil(bbounds.size().y* 4), (blob) => window.open(blob), {bounds: bbounds, margin: 0});
Manual screenshot of the viewer
Returned image of getScreenShotWithBounds
Update:
I misunderstood the function. Autodesk.Viewing.ScreenShot.getScreenShotWithBounds just fits the bounds into the camera view. The bounds are not used for any cropping. See my more detailed answer.
The given width and height of Autodesk.Viewing.ScreenShot.getScreenShotWithBounds must be of the same aspect ratio as the viewer (see Adam Nagy's answer), i.e.:
getScreenShotWithBounds(NOP_VIEWER, NOP_VIEWER.getDimensions().width * 4, NOP_VIEWER.getDimensions().height * 4, options);
getScreenShotWithBounds just fits the bounds into the camera view (internally it calls viewer.navigation.fitBounds(true, bounds, false);). The bounds are not used for any kind of cropping / pixel calculation or otherwise.
To get a specific aspect ratio by cropping, you have to provide getCropBounds in the options parameter.
For example to force a aspect ratio by cropping:
getCropBounds: function(viewer: Autodesk.Viewing.Viewer3D, camera: Autodesk.Viewing.UnifiedCamera, bounds: THREE.Box3): THREE.Box2 {
// calculate the crop bounds in pixels
// if the crop bounds are larger the screenshot's width / height is taken
const aspectRatio = new THREE.Vector2(4, 3);
const viewerBoundsWidthRatio = width / aspectRatio.x;
const viewerBoundsHeightRatio = height / aspectRatio.y;
const cropToHeight = viewerBoundsWidthRatio > viewerBoundsHeightRatio;
const smallerScaleRatio = cropToHeight ? viewerBoundsHeightRatio : viewerBoundsWidthRatio;
const cropBoundsSize = aspectRatio.clone().multiplyScalar(smallerScaleRatio);
const cropBounds = new THREE.Box2(new THREE.Vector2(0, 0), new THREE.Vector2(cropBoundsSize.x, cropBoundsSize.y));
const offset = cropToHeight ? new THREE.Vector2((width - cropBoundsSize.x) / 2, 0) : new THREE.Vector2(0, (height - cropBoundsSize.y) / 2);
cropBounds.min.add(offset);
cropBounds.max.add(offset);
return cropBounds;
}
The squashed image you are getting is suggesting it, but it's not clear from the comments in the source code, that you should keep the ratio of the Viewer for the width and height input parameters. So you should only scale them depending on your needs: getScreenShotWithBounds(NOP_VIEWER, viewer_width * x, viewer_height * x, etc
Then the bounds in the options should take care of the cropping.

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

Calculate aspect ratio of an image to get equal heights with flexbox

I was taking a look at:
this code pen about equal responsive height images
I want images to have the same height, despite their width/height differences.
As can be seen in the CSS below, there is usage of flexbox with flex to get the images as this:
/* Important stuff for this demo. */
img {
width: 100%;
height: auto;
vertical-align: middle;
}
.pics_in_a_row {
display: flex;
}
.img1 { flex: 1.3344; } /* <-- how can I calculate this part? */
.img2 { flex: 1.3345; }
.img3 { flex: 0.7505; }
.img4 { flex: 1.5023; }
.img5 { flex: 0.75; }
How can I calculate the part of the flex : number. I guess this is the aspect ratio?
The aspect ratio is X/Y of the image size.
So if the image is 600 pixels wide and 800 pixels high, the aspect ratio would be 600/800=0.75
When knowing this, you can choose one of the methods proposed in the article you referenced:
With the CSS methods, you do have a few options for specifying the
aspect ratio:
Work out the aspect ratio yourself and hard-code it into the CSS (as done in this demo)
Use CSS's calc() to calculate the aspect ratio (e.g. flex: calc(600/800);)
Use a preprocessor to calculate the aspect ratio at build time
I was struggling with this myself. You get the image ratio by dividing its width and height. If you don't use JavaScript just open your calculator and divide image width with the height. If you use JavaScript then to get the flex value you need to divide image width/height. Like this:
const imageRatio = img.naturalWidth / img.naturalHeight;
When getting the value you can use naturalWidth and naturalHeight values that return the original size of the image. I used only height and width in the beginning but it is from the browser and might return incorrect values in some cases (loading image etc).
https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/naturalWidth
What I ended up doing is that I calculate the column widths with JavaScript instead of the flex because it doesn't work if there is text inside the column. Then the math becomes more complex. You have to get the ratio of all images, sum them and you get the total ratio. Then you divide the image ratio with this full ratio to get the percentage.
Here is some pseudocode:
const getFullRatio = (images) => images.reduce((acc, curr) => (curr.naturalWidth / curr.naturalHeight) + acc, 0);
const containerWidth = 740;
const columnAmount = images.length;
const columnMargin = 15;
const marginPercentageToAdd = ((columnAmount * columnMargin) / containerWidth) + 1;
const fullRatio = getFullRatio(images);
const fullRatioWithMargins = fullRatio * marginPercentageToAdd;
images.forEach((img) => {
const imageRatio = img.naturalWidth / img.naturalHeight;
const columnRatio = (imageRatio / fullRatioWithMargins) * 100;
const imageParentDiv = img.closest('.COLUMNCLASS');
imageParentDiv.style.width = `${columnRatio}%`;
const image = img;
image.style.width = '100%';
});

How to resize a texture maintaining aspect ratio in libgdx

I have a .png image "circle.png".
The problem is when I try to resize this in sb.draw() method it disorientates (stretches). It works fine when I draw it with it's default size;
// inside constructor
{
Texture texture = new Texture("circle.png");
...
.
}
// render method
public void render (SpriteBatch sb){
sb.begin();
sb.setProjectionMatrix(camera.combined);
sb.draw(texture,x,y,100,100);// 100 for both width and height
sb.end();
}
//camera setup
camera = new OrthographicCamera();
camera.setToOrtho(false, width / 2, height / 2);
// width n height is 480x640
First image is one without resizing
Second image is while resizing
Your image is probably not a square. To maintain the aspect ratio, use math:
100 = texture.getWidth()/a
a = texture.getWidth()/100
So use:
sb.draw(texture,x,y,100,texture.getHeight()/(texture.getWidth()/100);
I hope it helps!
staticcasty