We had a strange problem with blurred images under Retina displays. Left part of the image - before, right one - after the fix.
Our QML code was using this code to show images:
Image {
anchors.verticalCenter: parent.verticalCenter
sourceSize.width: 25
sourceSize.height: 25
source: preview.url
}
I've tried to multiply sourceSize by Screen.devicePixelRatio - images became bigger so they did not fit their places.
Then I've replaced sourceSize.width with just width and the same for height. So:
Image {
anchors.verticalCenter: parent.verticalCenter
width: 25
height: 25
source: preview.url
}
And it works fine now.
My questions are:
Is it required to multiply sourceSize by devicePixelRatio? Or is it managed automatically? It seems that it is managed automatically for PNG and NOT managed for SVG.
If it is already managed automatically for PNG (these images preview.url are PNGs) then why was it blurred? The original PNG image is of size 64x64 pixels.
Why did images become bigger after I've multiplied sourceSize by devicePixelRatio?
Addition #1. I'm using data:// scheme in images' URLs. I.e.
QString url("data:");
url += imageMimeType;
url += ";base64,";
url += imageData.toBase64();
While referring to the other answer I gave you here, my understanding of the Qt code is that, outside from the cases described here, Qt does no scale that value. So my understanding seems to be the opposite of what you state in 1. What evidences led you to that statement?
Assuming this concept is correct (I may be incorrect), the reason for point 2, would be that Qt is loading a size that would be appropriate for 1x scaling. But for higher factors, there is a quality loss. If you are on retina, then you should adjust that value, or provide the #2x version.
As for point 3, the reason is probably in the docs: "if the width and height properties are not specified, the Image automatically uses the size of the loaded image". So if you double the size of the loaded image, you double the size of the element, as you are not setting width and height explicitly.
Setting width and height solves the problem because the image is loaded in full size, so it can draw with proper quality after the scaling.
Hope someone else can correct me if my understanding of Qt code is wrong.
Related
I am using NextJS and react-pdf/renderer and my tool creates a PDF and I'd like to display it with the PDFViewer component.
The Viewer loads but only takes up a small part of the screen. Whenever I change the 'width' and 'height' attribute with relative values (100%, 100vh), it won't take it. The only way to force it, is to put specific pixel values in it, but that defeats the purpose of being responsive to the screen size.
Sandbox that reproduces my issue: https://stackblitz.com/edit/nextjs-su5bi1?file=pages/index.js
Does anyone have an idea why this is happening?
Here is your screen with a red block of pixels of 150 pels high, note how it matches exactly your frame height.
Generally you ONLY set frame height in pixel units (The cross browser default minimum is 150?) you probably need somewhere to set a style defining the height as a different number of pixels.
see comment 2 in https://stackoverflow.com/a/73201090/10802527
I have a 4 channel png image with 8x8 Pixels that is loaded by a QImage. The QImage is then scaled by a factor of 200, so the image will have a new resolution of 1600x1600, each original pixel having a size of 200x200. But when this image is added to a QLabel through the means of a QPixmap and shown on screen, the drawn pixels will have slightly different sizes.
I've taken screenshots with Gimp and looked at the painted image more closely. It seems that every other pixel is slightly bigger than it should be, 201 instead of 200 pixels wide for example. The very last pixel in a row will then be smaller to compensate, so that the entire image has the correct size in the end.
This does not happen for all scaling factors, 100 is fine for example and so are factors that are a power of 2, such as 256.
My original approach was using a QGraphicsView and a QGraphicsPixmapItem in which case I scaled the GraphicsItem instead of the image. The effect was the same.
What effect am I seeing here? And what, if anything, can be done about it?
The code to reproduce this issue is very straightforward
int scale = 200;
image = QImage("some image file");
QPixmap pixmap = QPixmap::fromImage(image.scaled(image.size() * scale));
some_label->setPixmap(pixmap);
Turns out the easiest solution to my problem is to use QOpenGLWidget in the QGraphicsView:
setViewport(new QOpenGLWidget);
This single line in the constructor will result in much higher precision when scaling an image with the caveat of adding OpenGL as a dependency.
Another gotcha with this approach is that calling setViewport invalidates many of the settings done on a QGraphicsView. So if the view is set up in a UI file, as in my case, make sure to call other setters after calling setViewport.
I could not find a better solution that would work without OpenGL, short of writing my own rasterizer of course.
I want to resize images with different sizes with rmagick using only the width. I need to keep the proportions in example 640px width. The point is, if image is bigger than 640px, it should be made smaller to 640px. However, if the image is smaller than 640 it should not scale to 640, it should do nothing.
I thought this was the purpose of change_geometry, but somehow is not working for me. This is my example, but it´s always scaling all images to 640px.
photo = Magick::Image.read(name).first
photoMedium = photo.change_geometry!("640") { |cols, rows, img|
img.resize!(cols, rows)
}
# ... write photoMedium
UPDATE:
Well, I thought that was the purpose of change_geometry. Anyway, I guess you can always check the columns and if it´s bigger than 640 the resize, otherwise do nothing.
Check out the resize_to_fit method.
I am wondering if it is possible to shrink an image widget down to a size that is smaller than the image resource itself. I have tried the following:
imageResource.setSize(size, size);
imageResource.setPixelSize(size, size);
I have also tried re-sizing in the CSS file. But when I size the image to smaller than the original, it just crops it down and doesn't actually shrink it. It seems to me the solution is to use a high resolution, smaller image that I can scale up if need be, but I feel like I'm missing something here.
You can use CSS3 background-size property to scale the image:
http://www.w3schools.com/cssref/css3_pr_background-size.asp
Note that it's not supported in some very old browsers.
You can also try with,
ImageResorce myImage = new ImageResource();
myImage.getElement().setAttribute("height","20px");
myImage.getElement().setAttribute("width","20px");
cheers !!!
I'm working on a program to run Harmattan (N9) apps on Fremantle (N900). One of the problems is the resolution difference.
N900 has 800x480 screen and N9 854x480. Because of this part of the screen is cut off.
Can I fool (something) so that it thinks that the 800px screen contains 854px and paints all the elements (all the elements are painted as if 854px were availabe). I know that the shapes will be unnatural due to resizing one dimension, but it's better than a cut-off layout.
This has to be done without recompilation, as I can't access source code of every application for N9. I can't edit the qml files as they're built-in into qrc
Thanks in advance
marmistrz
If you code for different sizes of screens, you had better not use the raw values of screen dimensions. What you can do is saying that "this item with fill pw% of the width and ph% of the height". It will be automatically resized with the property binding. In your QML code, you can write something like this :
MyItem {
id: my_item
width: (pw / 100) * screen_width
height: (ph / 100) * screen_height
// ...
}