adding outline for image in qgraphicsitem with different image resolution - qt

Im trying to paint a image with outline in a qgraphicsitem . this image will have different resolution (640x380, 1190* 780, 320 *410) and i have to draw a constant 4px outline irrespective to the image width and height . i tried to take the percent of the image geometry but for different size of image the outline is changing . for higher resolution it looks thin and for smaller value thin line .
QFont segoeFont("Segoe Regular");
segoeFont.setPointSize(10);
painter->setFont(segoeFont);
painter->setRenderHints(QPainter::TextAntialiasing);
painter->setBrush(QColor(69,69,69));
if(meIsSelected)
{
painter->setBrush(QColor(65, 167, 243));
QPen pen(QColor(65, 167, 243), 2);
pen.setCosmetic(true);
}
painter->drawRect (this->boundingRect ());
painter->drawImage (QPoint(0,0), mePixmap);
and my boundingRect()
return mePixmap.rect ().adjusted (-4, -4, 4, 4);
this item is shown in view with fitInview
void GraphicsView::resizeEvent(QResizeEvent *event)
{
QGraphicsView::resizeEvent(event);
fitInView(this->scene()->sceneRect (),Qt::KeepAspectRatio) ;
}

If you need a constant 4px outline and the screen resolution is changing, what you're seeing is correct.
A 4px outline will, naturally look smaller with a higher resolution. In theory, if the resolution were just 4 pixels wide, it would take up the whole width of the screen, but with an 8px wide resolution, the 4px line would cover just half the screen. In both cases, the outline is still 4px.
If your screen resolution is the same and it's just the image resolution that's changing, then you need to show your code of how you're trying to render the outline.

Related

Floating QDockWidget resize - Change size of the resize handler/grip on the border

I have a simple Qt Mainwindow with a QDockWidget in it (Frameless Window).
Now when the QDockWidget is undocked it can be resized by clicking the border of it and drag to new size.
The problem is, that the border is only 1 or 2 pixels wide and it is almost impossible to catch it on a big high resolution screen.
Is there any way to set the size of the border that can be grabbed to more than 1 pixel?
(I do not want to use a QSizeGrip)
Try :
QDockWidget > QWidget {
border: 12px solid purple;
}
QDockWidget* dock = new QDockWidget();
dock->setStyleSheet("QDockWidget { margin: 4px; }");
This will set the dock widget margin to 4 pixels, which matches the default width of the resize grip set by QWidgetResizeHandler set unless it's target widget inherits from QFrame (QDockWidget does not).

How to fill the void with transparent background when rotating a QImage?

When I rotate an image in Qt, It automatically enlarge the image to encapsulate the bigger dimensions which is great and intelligent. However, it fills the newly created void with white color which is not what I want. How can I make it fill with a totally transparent color?
Here is may code.
QImage lSource("/path/to/an/image/file");
QTransform lRotation;
lRotation.rotate(30.0);
QImage lRotated(lSource.transformed(lRotation, Qt::SmoothTransformation));
ui.labelImage->setPixmap(QPixmap::fromImage(lRotated));
Thanks a lot!
Based on my comment above...
I suspect, that the void areas of the rotated image are transparent, and the white color is the background color of your label. If you want to set a specific background to your rotated image, you can do the following:
// Create rotated image.
QImage lSource("source.png");
QTransform lRotation;
lRotation.rotate(30.0);
QImage lRotated(lSource.transformed(lRotation, Qt::SmoothTransformation));
// Create resulting image with specific background.
QImage img(lRotated.size(), QImage::Format_ARGB32);
img.fill(Qt::red); // Set the red background
QPainter p(&img);
p.drawImage(0, 0, lRotated);
QLabel l;
l.setPixmap(QPixmap::fromImage(img));
l.show();

HTML5 Canvas fills windows with full resolution

I am trying to achieve a layout like this:
where:
Navbar is just a bootstrap-like top menu, 60px of height, always on top
Pop-up menu is fixed in that position (not always visible), always on top
The entire free area (windows w.o. navbar) is filled with Canvas.
Live example: jsFiddle
I have a problem with Canvas. I currently have a simple style:
<canvas id="le_canvas">Y U NO CANVAS</canvas>
...
#le-canvas {
position:absolute;
width:100%;
height:100%;
}
and the canvas is filling the background, but:
the resolution is very low
it doesn't maintain ratio during window resizes.
What I'd like (if it is possible):
full resolution of the area to fill (1:1 pixel on canvas and on screen)
set the ratio of the area to fill
bonus: update the above after window resize
Setting the canvas element in per-centage will not set the actual canvas size which must be set in absolute pixels. What happens here is that you get a canvas with a default size which then is stretched by the html-rendering giving the blurry look.
You therefor need to set the size by using f.ex. the window's sizes in absolute pixels.
You can do this like this (update of fiddle here: http://jsfiddle.net/x5LpA/3/ ) -
Create a function that sets the canvas size based on window size (you will of course need to subtract height of bars etc, but to show the principle):
function initCanvasArea(cnv) {
cnv.width = window.innerWidth;
cnv.height = window.innerHeight;
}
As the canvas content are cleared when the canvas is re-sized you need to render the content again for each time. Therefor it will be smart to extract the render content into a separate function like f.ex:
function renderCanvas(ctx) {
ctx.fillStyle = "rgb(200,0,0)";
ctx.fillRect(0, 0, 55, 50);
ctx.fillStyle = "rgba(0, 0, 200, 0.5)";
ctx.fillRect(20, 20, 55, 50);
}
Now, make the main function a self-invoking one where you also attach an event handler for windo.resize to update the canvas:
$(function () {
var canvas = $('#le_canvas')[0];
var ctx = canvas.getContext('2d');
initCanvasArea(canvas);
renderCanvas(ctx);
window.onresize = function(e) {
initCanvasArea(canvas);
renderCanvas(ctx);
};
})();
And finally edit the CSS-rule by removing the width/height set to 100%;
#le_canvas {
position:absolute;
}
(Tip: a better approach here is to use the fixed attribute for position - plus use a wrapper element, padding, box-sizing.. but that is out of scope for this question).
Is this what you are after? I used $(document).width() and $(document).height() to get the width and height for the rectangle. http://jsfiddle.net/x5LpA/1/

How to invert QImage without affecting performance?

I have a QImage in a QGraphicsView which I need to show images continously. Some times I need to show the inverted images continuously. For this I use
img.invertPixels(QImage::InvertRgba);
But at this time, the display is flickering due to the continuous inverting process. How can I implement the inverting process without affecting the performance? The display seems to be smooth without invert. `
QImage img(byImageBuf, width, height, QImage::Format_Indexed8);
scene->clear();
if(bInvertPixel)
{
/* Inverted image */
img.invertPixels(QImage::InvertRgba);
}
scene->addPixmap(QPixmap::fromImage(img));
view->fitInView(0, 0, width, height, Qt::IgnoreAspectRatio);
view->update();`
Since you are using an indexed image type (QImage::Format_Indexed8) you can invert the color table and just toggle that:
if(bInvertPixel)
{
/* Inverted image */
img.setColorTable( invertedColorTable );
}
else
{
img.setColorTable( standardColorTable );
}
standardColorTable and invertedColorTable are arrays of QRgb values.
The beauty of the color table is that you do not have to update it every time you display your image; just set it once and forget about it. Connect a signal from a button for inverting the colors and set the color table there.

Qt : draw triangle image

I need to do something similar to QPainter::drawImage, but drawing a triangle part of the given picture (into a triangular region of my widget) instead of working with rectangles.
Any idea how I could do that, besides painfully trying to redraw every pixel?
Thanks for your insights!
If it is feasible for you to use a QPixmap instead of a QImage, you can set a bitmap mask for the QPixmap which defines which of the pixels are shown and which are transparent:
myPixmap->setMask(myTriangleMask);
painter->drawPixmap(myPixmap);
Here is another solution based on QImage:
MaskWidget::MaskWidget(QWidget* parent) : QWidget(parent) {
img = QImage("Sample.jpg"); // The image to paint
mask = QImage("Mask.png"); // An indexed 2-bit colormap image
QPainter imgPainter(&img);
imgPainter.drawImage(0, 0, mask); // Paint the mask onto the image
}
void MaskWidget::paintEvent ( QPaintEvent * event ) {
QPainter painter(this);
painter.drawImage(10, 10, img);
}
Mask.png is an image file with the same size as Sample.jpg. It contains an alpha channel to support transparency. You can create this file easily with The GIMP, for example. I added an alpha channel, changed all areas I want to have painted to transparent and all other areas to white. To reduce the size, I finally converted it to an indexed 2-bit image.
You could even create the mask image programmatically with Qt, if you need your triangle be computed based on various parameters.

Resources