drawing text in PlayN doesn't appear - playn

I'm trying to draw a rectangle with text on it, but all I see is the rectangle, there is no text. Am I doing something wrong?
This is the part of the code that does the drawing:
CanvasImage image = PlayN.graphics().createImage(100, 50);
Canvas canvas = image.canvas();
canvas.setFillColor(color);
canvas.fillRect(0, 0, 100, 50);
canvas.setFillColor(textColor);
canvas.setStrokeColor(textColor);
canvas.drawText("test", 0, 0);
layer.surface().drawImage(image, 0, 0);
Thanks
btw, I'm running the HTML version.

The problem was that the text is drawen up from the y coordinate and I was setting y to 0 so the text wasn't shown.

Related

Why is this code shrinking my image?

I've take some code and reduced it down to a few lines which still reproduce the error i am having. In this case, I am taking an image that is 448x298 in size and trying to overlay it on top of a white background that's 600x450.
So I'm expecting to get an image that's 600x450 with a white background and my original image laid on top of it starting in the upper right corner. And i expect my original image to remain it's original size. Instead the original image is going from 448x298 to approximately (give or take a pixel or two) 143x95
Here is the reduced code that's doing this:
System.Drawing.Image oImage = new Bitmap(600, 450);
Graphics oGraphic = Graphics.FromImage(oImage);
oGraphic.FillRectangle(Brushes.White, 0, 0, 600, 450);
oGraphic.DrawImage(image, new Point(0,0));
return (Bitmap)oImage;
You have to specify the target size. The overload you chose scales the image from the source dpi to the target dpi. As explained in another question, you should do this:
System.Drawing.Image oImage = new Bitmap(600, 450);
Graphics oGraphic = Graphics.FromImage(oImage);
oGraphic.FillRectangle(Brushes.White, 0, 0, 600, 450);
oGraphic.DrawImage(image, 0,0, image.Width, image.Height);
return (Bitmap)oImage;

QGraphicsView to pdf

I have a big scene successfully displayed in my window with the help of QGraphicsView/QGraphicsScene with scroll bars for navigation. Everything works fine.
Now I would like now to render part of the scene in a pdf. The region to be render in the pdf should be the area visible in the window and the rectangles above and under the visible area.
I've tried that (to begin simply, I've ignored if horizontal scroll bar have been used) :
QPrinter myPrinter(QPrinter::ScreenResolution);
myPrinter.setOrientation(QPrinter::Landscape);
myPrinter.setPaperSize(QPrinter::A4);
myPrinter.setOutputFormat(QPrinter::PdfFormat);
myPrinter.setPageMargins(0.0, 0.0, 0.0, 0.0, QPrinter::Point);
QPainter myPainter(&myPrinter);
m_pageWidth = myPrinter.width();
m_pageHeight = myPrinter.height();
myPainter.setViewport(0, 0, m_pageWidth, m_pageHeight);
QRectF viewRender = QRect(0.0, 0.0, m_pageWidth, m_pageHeight);
for(int i = 0; i < myScene->getNbPages(); i++)
{
QRect viewScene = QRect(0, m_pageHeight * i, m_pageWidth, m_pageHeight);
setSceneRect(viewScene);
render(&myPainter, viewRender, viewScene);
if(i + 1 < myScene->getNbPages())
myPrinter.newPage();
}
But I don't get result as I would expect. For example in this function QGraphicsView::drawBackground(QPainter *painter, const QRectF &rect) rect's top left corner is not at 0, 0 for the first page, but a 107, 98, then at 107, 1585 (but page height is only 793 ?!) and so on...
Anyone understand what is going on ? Thanks for reading.
http://qt-project.org/doc/qt-4.8/qgraphicsview.html#mapToScene
http://qt-project.org/doc/qt-4.8/qgraphicsview.html#mapFromScene
Use one or the other of those appropriately and you should get the results you want.
For example you might try:
render(&myPainter, this->mapToScene(viewRender), viewScene);
// assuming this is your QGraphicsView instance
I demoed how to use this in another question I answered:
How to draw a point (on mouseclick) on a QGraphicsScene?
Hope that helps.

How do I combine a QImage and QPixmap?

I'm using PyQt, and I've loaded an image from disk into a QPixmap. I've also created a mask, using:
self.mask = QImage(self.image.width(), self.image.height(), QImage.Format_Mono)
self.mask.fill(0)
I'd like to combine the two for display, such that any pixels colored black in the mask are drawn in translucent red over the image when I render it.
I've created a custom widget, that renders the image in the paint event like so:
def paintEvent(self, event):
p = QPainter(self)
r = event.rect()
p.drawPixmap(r, self.image, r)
This works fine. What I'm less clear on is how to take the data in the mask and paint a translucent red only over those pixels in the destination image.
I've tried turning the mask into a clipping region, like this:
mask = QPixmap.fromImage(self.mask.createMaskFromColor(self.mask.color(0)))
p.setClipRegion(QRegion(mask))
color = QColor(255, 0, 0, 128)
p.setPen(Qt.NoPen)
p.setBrush(QBrush(color))
p.drawRect(r)
... but it doesn't draw anything (and draws a translucent red box over the whole image if I don't call setClipRegion).
I also tried creating the mask as a QImage.Format_ARGB4444_Premultiplied, and using transparency. And while this does work, and I can edit the mask in my program (and verify that some portions of the mask are transparent and some portions are opaque) the self.mask.createAlphaMask() method returns a solid white rectangle.
Do the "create mask" methods actually do anything?
Either change your mask's design or create a new QImage based on your mask. Then draw the QImage on the destination. It is not only a method that works, but also a method that is faster than drawing single pixels or sth. similar. I tried several ways and this was the fastest so far (on a QGLWidget).
The idea is that you encode the transparency, and also the non-marked pixels, in the QImage directly, like this:
QImage dest(<width>, <height>, QImage::Format_ARGB32);
dest.fill(qRgba(0, 0, 0, 0));
for (int y = 0; y < <height>; ++y) {
QRgb *destrow = (QRgb*)dest.scanLine(y);
for (int x = 0; x < <width>; ++x) {
if (<should be marked>)
destrow[x] = qRgba(255, 0, 0, 127);
}
}
painter.drawImage(0, 0, dest);
For reference, take a look at the code here:
https://sourceforge.net/p/gerbil/svn/60/tree/trunk/gerbil-gui/bandview.cpp#l59

Wrong alpha blending when rendering on a QGLFramebufferObject

I write an OpenGL based vector graphics renderer for my application. It needs to render to a framebuffer object rather to the screen directly. Since I write the application in Qt, I use a QGLFramebufferObject which is a wrapper class for a OpenGL framebuffer object.
I created a minimal example which shows a wrong result I also get when rendering more complex stuff (for example using a fragment shader which sets colors with a non-one alpha value). I just render a red circle and a half-transparent green one on a black cleared screen, and then the same on the FBO:
void MainWidget::initializeGL()
{
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glClearColor(0, 0, 0, 0);
}
void MainWidget::resizeGL(int w, int h)
{
glViewport(0, 0, w, h);
}
void MainWidget::paintGL()
{
// DRAW ON THE SCREEN
{
glClear(GL_COLOR_BUFFER_BIT);
glPointSize(100);
glEnable(GL_POINT_SMOOTH);
glBegin(GL_POINTS);
glColor4f(1, 0, 0, 1);
glVertex2f(-.2, 0);
glColor4f(0, 1, 0, .5);
glVertex2f( .2, 0);
glEnd();
}
QGLFramebufferObject fbo(width(), height());
fbo.bind();
// DRAW ON THE FBO USING THE SAME CODE AND THE SAME CONTEXT
{
glClear(GL_COLOR_BUFFER_BIT);
glPointSize(100);
glEnable(GL_POINT_SMOOTH);
glBegin(GL_POINTS);
glColor4f(1, 0, 0, 1);
glVertex2f(-.2, 0);
glColor4f(0, 1, 0, .5);
glVertex2f( .2, 0);
glEnd();
}
fbo.release();
fbo.toImage().save("debug.png");
}
The result looks like this on the screen (scaled 400%):
The rendering to the QGLFramebufferObject looks like this (also scaled 400%):
Note that this image is not fully opaque, so here it is the same image with a checkerboard added behind it:
Even the area in which the two circles overlap isn't fully opaque. And the anti-aliasing looks pretty ugly.
How does this happen? And how can I fix this?
I already tried:
Different blend functions.
Explicitly disabling the depth buffer, stencil buffer and sampling on the QGLFramebufferObject. I'm not sure if the QGLFramebufferObject default format adds something I don't want.
Try the following:
QGLFramebufferObjectFormat fmt;
fmt.setSamples(1); // or 4 or disable this line
fmt.setInternalTextureFormat(GL_RGBA8);
QGLFramebufferObject fbo(width(), height(), fmt);
This forces a specific pixel format and also disables rendering to a texture by using multisampling (otherwise QT always renders to a texture). That might produce different results. You can also experiment with the format.
Also, what is your hardware? My maximal point size is only 64 pixels (GTX 260), you are trying to render 100 pixel points. That might be an issue. Are any OpenGL errors generated? Does the same happen on small points?
You might also try hinting (if it's possible in QT):
glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);
But i wouldn't expect this to change anything.

How to add an image on the top of another image?

I want to show difference between a trimed clip and non trimed clip in my video editor application, i.e. I want to add a small film image on my thumbnail for a trimed clip. How can I do this?
It would be just to show the difference between an image and a video in our gallery application.
How to add an image on the top of another one in Qt?
Open the QPainter on the bottom image and draw the top image using its drawPixmap()/drawImage() methods.
QPixmap base, overlay; // come from your code
{
QPainter painter(base);
painter.drawPixmap(100, 100, overlay);
}
If your overlay contains an alpha channel (e.g. fancy PNG icon) and your base image does not, you should create a new QPixmap with an alpha channel and draw both images into it:
QPixmap base, overlay; // come from your code
QPixmap result(base.width(), base.height());
result.fill(Qt::transparent); // force alpha channel
{
QPainter painter(&result);
painter.drawPixmap(0, 0, base);
painter.drawPixmap(100, 100, overlay);
}
QPixmaps and QImages can be used interchangeably, although not all combinations give good performance).
If it's just about showing an image above another, then you could also go with this answer.
QGridLayout *layout = new QGridLayout(widget);
Pixmap base, overlay;
QLabel *background = new Label();
background->setPixmap(&base);
QLabel *lOverlay = new QLabel();
lOverlay->setPixmap(&overlay);
//label gets positioned above textBrowser and is an overlay
layout->addWidget(background, 0, 0, Qt::AlignLeft | Qt::AlignTop);
layout->addWidget(lOverlay, 0, 0, Qt::AlignRight | Qt::AlignBottom);
Of course then the QPixbuf of the background doesn't contain the QPixbuf of the overlay-image, but it only appears to do.

Resources