Add a border to a QPixmap - c++

I load a QPixmap from a file. I want to add a border around the QPixmap, say 4px white on each side.
What is the fastest way to do this? Do I have to create a second larger QPixmap and draw the first into the second or is there some way to extend the existing one without scaling (I've noticed that there is a QPixmap::transformed() but don't know if this is suitable in my case.

Do I have to create a second larger QPixmap and draw the first into the second
Yes.
is there some way to extend the existing one without scaling
Yes. The larger pixmap will take an unscaled copy of the original one.
The foregoing assumes that you care about the resulting pixmap. If you don't care about it, but only care to display the pixmap on a window/widget with some border, then simply draw the border and pixmap separately using QPainter, OpenGL geometry, etc.

Related

Drawing text with shadow on pixmap with QPainter

I am working on a project in C++ with Qt, and I am trying to find a way to apply a text shadow when drawing text on a QPixmap using QPainter.
I understand that QGraphicsDropShadowEffect is a thing, and I am using in other parts of my project, but I can't for the life of me find a way to apply a QGraphicsEffect when drawing with QPainter on a pixmap. Drawing the same text multiple times with different offsets and opacities doesn't quite cut it.
Are there any ways to do this?
If not, how could I go about making a function that does it, given a QGraphicsEffect to get the radius and color from?
Thanks in advance!
I don't think it is directly possible to "draw text with shadow", it is only possible to apply a shadow to something already drawn that would take in an element and use say its alpha channel to calculate the shadow.
You should use composition, either of the final products or during drawing. It should work if you use it on a text element. The other option would be to draw your text in black, apply Gaussian blur and then again draw the text on top of it with the desired offset.
Thanks for your answer ddriver, it made me search with some new keywords, which lead me to find a suiting solution for my project.
What I figured out is that you can simply create a QLabel with the text and effects you want (QGraphicsDropShadowEffect, in my case), and render it into a QPixmap using QWidget::grab(). You can then draw this new pixmap with QPainter as you would any other image, by converting your pixmap to a QImage and using QPainter's drawImage().

Qt - Grabbing pixmap from a Widget doesn't take proper alpha channel

I'm currently using the QWidget::grab() function to acquire a QFrame's pixmap (and all of its children), but the function doesn't seem to take into account if the widget doesn't have any background.
You see, my QFrame is set to "setAutoFillBackground(false)", but when its pixmap is grabbed, it seems to paint the default light-pinkish background instead of full transparency.
Replacing the pixmap with a picture containing an alpha channel works fine.
The situation I'm using this in is with QGL, so the pixmap is getting rendered later on as a texture.
I changed the frame's palette's background to contain 0 alpha. This fixed the program.
Although I still believe that the grab function should take into account the bool that was set for filling the background or not - since not autofilling the background equates to the same net visual effect normally, just not when grabbed.

(Qt C++) Resize pixmap and KEEP pixelation?

In my project I have a QLabel that I change the pixmap frequently like this:
ui->frameLabel->setPixmap(slot_pic[blockId[currentSlot]][damageId[currentSlot]]);
slot_pic is simply a 2d map. So you can look at it clearer like this:
ui->frameLabel->setPixmap(pixmap);
The image is 16x16 in size and my label is 32x32. I have scaledContents checked so when the pixmap changes, the image is double in size. However, the image is now blurry. I understand why, but I was wondering if there is a way to make it stay pixelated. I want to just have a bigger pixelated image. (The image is from Minecraft if that helps you understand what I mean)
Thanks for your time :)
Don't let the QLabel do the scaling. Instead, do the scaling by yourself using QPixmap::scaled(). Something like this:
ui->frameLabel->setPixmap(
pixmap.scaled(32, 32, Qt::IgnoreAspectRatio, Qt::FastTransformation));
The important parameter is the last one, transformMode, which tells whether bilinear filtering is used or not.

overlay support in windows/opengl environment

I have to display an image and text overlay, when text overlay contains many strings, but only one changes from frame to frame. I want to avoid redraw of the entire overlay and only update what has changed.
I tried wglCreateLayerContext but my GPU seems to not support it (PIXELFORMATDESCRIPTOR bReserved is 0).
What is the most efficient way to redraw only part of text overlay?
Redrawing the whole framebuffer is the canonical way in OpenGL. You can use Framebuffer Objects (FBO) to create several off-screen drawing surfaces, to which you render the individual layers. Then you composit the layers into a composite image presented on screen.
but only one changes from frame to frame. I want to avoid redraw of the entire overlay
Why? Figuring out what parts need redraw, masking them, do only a partial clear, updating it, etc. takes more time and effort than to simply redraw the whole text overlay.

Maximum Size of QPixmap/QImage Windows

I have a QGraphicsView for a very wide QGraphicsScene. I need to draw the background in drawBackground() and the background is a bit complicated (long loop) although it doesn't need to be repainted constantly. I store it in a static QPixmap (I tried QImage too) inside the function drawBackground() and that pixmap is what I draw onto the painter of the view. Only when needed is the QPixmap painted on again.
If I didn't use a static pixmap, the complicated background would be generated every time I scroll sideways for example. The problem is that apparently there is a maximum width for pixmaps on Windows, on my computer it's 32770. I could store a list of pixmaps and draw them side by side but it would make the code uglier and I also don't know what the maximum width of a pixmap is for every Windows machine. Since this might be a well-known problem I was wondering if anyone has a better solution.
Thanks.
You can probably avoid the windows limit by using unaccelerated raster paint device, but 32770*1024 is 100MiB of pixmap; you probably don't want to do that even if Windows would let you.
You've already thought of the usual answer (tile it in more reasonably-sized chunks and load/generate them on demand). The other piece of the usual solution is to use something like QPixmapCache to keep the recently-used tiles so you don't regenerate them too often (only when the user scrolls a long way).
You didn't say how complex your complex background is, but you might also want to look at the Mandelbrot set example for how to do piecewise rendering of an (infinitely) large background pixmap on-demand, without blocking the UI.
This is the common use case for the tiling pattern. Basically you split the background into small images.
I'm not sure why you think "it would make the code uglier". It is certainly not a one-liner. Depending whether you have fixed size background image or not, the tiling code is usually pretty straightforward.