How to maintain and apply aspect ratio of images in extjs4 - image

I am working in extjs4. I am trying to display image by using following component=
xtype : 'image',
height : 600,
width : 800,
src :me.imageSrc
Where,me.imageSrc is having image path. But sometimes image is shown as blurred or expanded if image's height and width is too large. So how to calculate aspect ratio and apply it in extjs4 in order to show images properly.

In order to get the size of the loaded image you need to listen the "load" event on the image element, in the listener callback you have access to the with and height.
Here's the code that makes the magic:
var img = imageCmp.imgEl
img.on('load',function(){
Ext.Msg.alert('IMG Size',img.getWidth()+'x'+img.getHeight());
});
Here's a working example:
http://jsfiddle.net/crysfel/utUA2/
Make sure you remove the hardcoded width and height ;)

Related

GraphQL Gatsby Plugin Image set max-width to size of original image

I am using Google Photos to host photos for a website I am managing, and accessing them via GraphQL and Gastby (gatsby-image-plugin)
The images are shown in a gallery, but open up in a light-box gallery slider - I'm using FancyApps/ui (v4.x). Anyway the maximum size of the images are the maximum size of the source set (i.e. 512px). This means on a big screen the full screen image looks small (only 512px wide). You can see these values on the screen-grab below:
"original": {
"width": 512,
"height": 341
}
The original image is 1200px width, which is confirmed by the media metadata:
"mediaMetadata": {
"height": "800",
"width": "1200"
}"
Which is the same as images > sources > sizes:
"sizes": "(min-width: 512px) 512px, 100vw"
I realise I can force the value by specifying gatsbyImageSharp to have a width of 1200.
{
allGooglePhotosAlbum(filter: {title: {eq: "assorted"}}) {
nodes {
title
photos {
file {
childImageSharp {
id
gatsbyImageData(placeholder: BLURRED, width: 1200)
original {
width
height
}
}
}
mediaMetadata {
height
width
}
}
}
}
}
However some of the images are not 1200px wide (i.e. the portrait images), I get the following warning:
The requested width "1200px" for a resolutions field for the file URL_HERE was larger than the actual image width of 512px! If possible, replace the current image with a larger one.
I don't like the warning, but more importantly I think this might make the height of the image too large to be displayed properly (i.e. either would be cropped or larger than the screen height - 100vh).
Surely there, should be a way to set the largest image width/height to the heights provided by the media metadata (i.e. the full un-adulterated image).
I don't think you need to play along with the width of the image rather than the layout display, otherwise you will face the issue you mention (some images has 1200 but not all of them, plus adding a scaling that may not fit all the images constraints).
That said, I think you can simply do something like:
{
allGooglePhotosAlbum(filter: {title: {eq: "assorted"}}) {
nodes {
title
photos {
file {
childImageSharp {
id
gatsbyImageData(placeholder: BLURRED, layout: FULL_WIDTH)
original {
width
height
}
}
}
mediaMetadata {
height
width
}
}
}
}
}
The specs about FULL_WIDTH:
Use this for images that are always displayed at the full width of the
screen, such as banners or hero images. Like the constrained layout,
this resizes to fit the container. However it is not restricted to a
maximum size, so will grow to fill the container however large it is,
maintaining its aspect ratio. It generates several smaller image sizes
for different screen breakpoints, so that the browser only needs to
load one large enough to fit the screen. You can pass a breakpoints
prop if you want to specify the sizes to use, though in most cases you
can allow it to use the default.
That way, the displayed images won't be constrained by their own constraints, but they will be by the container where they are displayed, allowing you to play around with CSS rules to customize them. In addition, the browser will only take the image that needs to fit the screen.
Just incase anyone else has this issue, I have managed to figure it out. It turns out that it wasn't related to the graphQL query at all, but rather with the gatsby-source-google-photos plugin I was using.
The this plugin has the option to set the maxHeight and maxWidth - these values are both 512px by default. Which was why that was the maximum image width I was seeing in my query was 512px (when the original image was 1200px). See the documentation
All I needed to do was to change these values to 1200px in my gatsby-config.js file and I got the larger images.

With canvas, ctx.lineTo draws a longer "Y" line than instructed (160 instead of 120) [duplicate]

I have 2 canvases, one uses HTML attributes width and height to size it, the other uses CSS:
<canvas id="compteur1" width="300" height="300" onmousedown="compteurClick(this.id);"></canvas>
<canvas id="compteur2" style="width: 300px; height: 300px;" onmousedown="compteurClick(this.id);"></canvas>
Compteur1 displays like it should, but not compteur2. The content is drawn using JavaScript on a 300x300 canvas.
Why is there a display difference?
It seems that the width and height attributes determine the width or height of the canvas’s coordinate system, whereas the CSS properties just determine the size of the box in which it will be shown.
This is explained in the HTML specification:
The canvas element has two attributes to control the size of the element’s bitmap: width and height. These attributes, when specified, must have values that are valid non-negative integers. The rules for parsing non-negative integers must be used to obtain their numeric values. If an attribute is missing, or if parsing its value returns an error, then the default value must be used instead. The width attribute defaults to 300, and the height attribute defaults to 150.
To set the width and height on a canvas, you may use:
canvasObject.setAttribute('width', '150');
canvasObject.setAttribute('height', '300');
For <canvas> elements, the CSS rules for width and height set the actual size of the canvas element that will be drawn to the page. On the other hand, the HTML attributes of width and height set the size of the coordinate system or 'grid' that the canvas API will use.
For example, consider this (jsfiddle):
var ctx = document.getElementById('canvas1').getContext('2d');
ctx.fillStyle = "red";
ctx.fillRect(10, 10, 30, 30);
var ctx2 = document.getElementById('canvas2').getContext('2d');
ctx2.fillStyle = "red";
ctx2.fillRect(10, 10, 30, 30);
canvas {
border: 1px solid black;
}
<canvas id="canvas1" style="width: 50px; height: 100px;" height="50" width="100"></canvas>
<canvas id="canvas2" style="width: 100px; height: 100px;" height="50" width="100"></canvas>
Both have had the same thing drawn on them relative to the internal coordinates of the canvas element. But in the second canvas, the red rectangle will be twice as wide because the canvas as a whole is being stretched across a bigger area by the CSS rules.
Note: If the CSS rules for width and/or height aren't specified then the browser will use the HTML attributes to size the element such that 1 unit of these values equals 1px on the page. If these attributes aren't specified then they will default to a width of 300 and a height of 150.
The canvas will be stretched if you set the width and height in your CSS. If you want to dynamically manipulate the dimension of the canvas you have to use JavaScript like so:
canvas = document.getElementById('canv');
canvas.setAttribute('width', '438');
canvas.setAttribute('height', '462');
The browser uses the css width and height, but the canvas element scales based on the canvas width and height. In javascript, read the css width and height and set the canvas width and height to that.
var myCanvas = $('#TheMainCanvas');
myCanvas[0].width = myCanvas.width();
myCanvas[0].height = myCanvas.height();
Shannimal correction
var el = $('#mycanvas');
el.attr('width', parseInt(el.css('width')))
el.attr('height', parseInt(el.css('height')))
Canvas renders image by buffer, so when you specify the width and height HTML attributes the buffer size and length changes, but when you use CSS, the buffer's size is unchanged. Making the image stretched.
Using HTML sizing.
Size of canvas is changed -> buffer size is changed -> rendered
Using CSS sizing
Size of canvas is changed -> rendered
Since the buffer length is kept unchanged, when the context renders the image,
the image is displayed in resized canvas (but rendered in unchanged buffer).
CSS sets the width and height of the canvas element so it affects the coordinate space leaving everything drawn skewed
Here's my way on how to set the width and height with Vanilla JavaScript
canvas.width = numberForWidth
canvas.height = numberForHeight
I believe CSS has much better machinery for specifying the size of the canvas and CSS must decide styling, not JavaScript or HTML. Having said that, setting width and height in HTML is important for working around the issue with canvas.
CSS has !important rule that allows to override other styling rules for the property, including those in HTML. Usually, its usage is frowned upon but here the use is a legitimate hack.
In Rust module for WebAssembly you can do the following:
fn update_buffer(canvas: &HtmlCanvasElement) {
canvas.set_width(canvas.client_width() as u32);
canvas.set_height(canvas.client_height() as u32);
}
//..
#[wasm_bindgen(start)]
pub fn start() -> Result<(), JsValue> {
// ...
let canvas: Rc<_> = document
.query_selector("canvas")
.unwrap()
.unwrap()
.dyn_into::<HtmlCanvasElement>()
.unwrap()
.into();
update_buffer(&canvas);
// ...
// create resizing handler for window
{
let on_resize = Closure::<dyn FnMut(_)>::new(move |_event: Event| {
let canvas = canvas.clone();
// ...
update_buffer(&canvas);
// ...
window.add_event_listener_with_callback("resize", on_resize.as_ref().unchecked_ref())?;
on_resize.forget();
}
}
There we update the canvas buffer once the WASM module is loaded and then whenever the window is resized. We do it by manually specifying width and height of canvas as values of clientWidth and clientHeight. Maybe there are better ways to update the buffer but I believe this solution is better than those suggested by #SamB, #CoderNaveed, #Anthony Gedeon, #Bluerain, #Ben Jackson, #Manolo, #XaviGuardia, #Russel Harkins, and #fermar because
The element is styled by CSS, not HTML.
Unlike elem.style.width & elem.style.height trick used by #Manolo or its JQuery equivalent used by #XaviGuardia, it will work for canvas whose size is specified by usage as flex or grid item.
Unlike the solution by #Russel Harkings, this also handles resizing. Though I like his answer because it is really clean and easy.
WASM is the future! Haha :D
P.S. there's a ton of .unwrap() because Rust explicitly handles possible failures.
P.P.S.
{
let on_resize = Closure::<dyn FnMut(_)>::new(move |_event: Event| {
let canvas = canvas.clone();
// ...
update_buffer(&canvas);
// ...
window.add_event_listener_with_callback("resize", on_resize.as_ref().unchecked_ref())?;
on_resize.forget();
}
can be done much cleaner with better libraries. E.g.
add_resize_handler(&window, move |e: ResizeEvent| {
let canvas = canvas.clone();
// ...
update_buffer(&canvas);
})
If you want a dynamic behaviour based on, e.g. CSS media queries, don't use canvas width and height attributes. Use CSS rules and then, before getting the canvas rendering context, assign to width and height attributes the CSS width and height styles:
var elem = document.getElementById("mycanvas");
elem.width = elem.style.width;
elem.height = elem.style.height;
var ctx1 = elem.getContext("2d");
...

How to display both portrait & landscape images into a square on the grid without disturbing the aspect ratio?

I am using a GridView to create a gallery of images that I display from a certain folder on my machine. The images are of different width*height ratios. Few are portrait images where the height of the image is like 3 times more than width. Some image are landscape like where the width is approx 3 times of height. And some images are squared.
The issue with my gallery is I have a square for each Image component of my GridView as you can see below. This makes the portrait & landscape images get incorrectly stretched as each block in the Grid is a square. Thus causing the aspect ratio of the image to get skewed up.
The Question:
How can I ensure that I display both portrait & landscape images into my square without skewing the aspect ratio? I am looking at putting some black/grey background on parts of the square which go blank on a portrait or landscape image? But there might be other tricks.
The code:
import QtQuick 2.5
import Qt.labs.folderlistmodel 2.1
import QtQuick.Controls 1.1
import QtQml.Models 2.1
GridView {
cellHeight: height/2
cellWidth: width/2
clip: true
FolderListModel {
id: dir_model
folder: "/path/to/images/folder"
nameFilters: ["*.png"]
}
Component {
id: file_delegate
Image {
width: (parent.width)/2
height: (parent.width)/2
source: fileURL
}
}
model: dir_model
delegate: file_delegate
}
Just set Image fillMode property to Image.PreserveAspectFit
As the doc says:
the image is scaled uniformly to fit without cropping

Resizing images in Etalage Jquery Zoom plugin using Javascript

I am working on a webpage that lists the details of a product .
The product details include an image that can be zoomed using the Etalage Jquery Zoom plugin.
I am able to change the image that is displayed in the Etalage Jquery plugin depending on certain attributes of the product.
I am dynamically changing the images by executing the statement
$('#etalage').etalage({
show_descriptions: false,
small_thumbs: 0
}).show();
The problem is that the source image looses its assigned height and width.
I would like to know how to assign a height and width to the source image using JavaScript
after changing the image in the Etalage plugin.
Regards
Mathew
Resolved this issue by observing the values that were being assigned to the
following parameters when the size of the source image was correct.
Assigning those values while calling the show() method solved my problem
$('#etalage').etalage({
show_descriptions: false,
small_thumbs: 0,
source_image_width: 900, // The source/zoomed image width (not the frame around it) (value in pixels)
source_image_height: 1200,
thumb_image_width:480, // The large thumbnail width (excluding borders / padding) (value in pixels)
thumb_image_height: 480,
autoplay:false,
zoom_area_width: 340, // Width of the zoomed image frame (including borders, padding) (value in pixels)
zoom_area_height:495, // Height of the zoomed image frame (including borders, padding) (value in pixels / 'justify' = height of large thumb + small thumbs)
zoom_area_distance: 20,
}).show();

IF image is too big, how do I reduce the size?

My Website
On the above link you can see that the middle news post has an image that is just too big.
The info for the news is taken out of a database so I'm not sure how to change the width of the image on only certain images. Ideally I'd like to have any image that is over 300px wide to be kept at 300px. This is what I have so far:
echo '<img src="media/'.$row['media1'].'" class="floatLeftClear" id="border">';
I tired adding width="300" to the above statement but that made ALL of the images become 300px which I don't want. I only want images bigger than 300px to be reduced to 300.
Can someone point me in the right direction please!
If you don't want to physically resize the images on the server, which would be the ideal solution, you can set the max-width property via CSS.
img {
max-width:300px;
}
Note that the property is not supported in IE6 and below.
The code helps to resizing the image. its resize the height and width depends upon the max width
function fixImgs(whichId, maxW) {
var pix=document.getElementById(whichId).getElementsByTagName('img');
for (i=0; i<pix.length; i++) {
w=pix[i].width;
h=pix[i].height;
if (w > maxW) {
f=1-((w - maxW) / w);
pix[i].width=w * f;
pix[i].height=h * f;
}
}
}
fixImgs('photos', 108); // ('element ID', maximum width)
But one thing the image size(KB) is not reduce. I hope its help to you .
Why not to add a special routine for news images layout, define max-size within it and call it for the related images?

Resources