Results 1 to 2 of 2

Thread: QPainter Antialiasing for QImage

  1. #1
    Join Date
    May 2010
    Location
    Germany
    Posts
    9
    Thanks
    1
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default QPainter Antialiasing for QImage

    Hi,
    first what I'm doing.
    I'm coding a small GUI system for a game I'm writing. The existing GUI Toolkits usable on Ogre3D don't convince me enought that I use them. I'd like to use Qt, I even tried it but had some major issues doing so (major performance loss, Mouse/Keyboard events not working, etc.). So I decided to write my own toolkit. I already did write one, but it was very dirty and I didn't write it as an own library but coded it directly to the game. So I decided to re-write it.

    Now my issue.
    When rendering the Widgets, everything is fine, until I add a border radius. I guess, an image showing it is way easier than explaining:
    click me
    I'm rendering directly on a QImage, using QPainter/QPainterPath.
    The Pen is defined as follows:
    Qt Code:
    1. painter.setPen(QPen(b, wB, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
    To copy to clipboard, switch view to plain text mode 
    The Brush is either a QColor or a QLinearGradient.
    As render hint I only use Antialiasing.
    The QImage is in the ARGB32 format.
    I tried both approaches for the border radius, arcTo and cubicTo. Both ways have the same issue.

    The problem occurs on different Graphics Systems.

    here is the code I use for the rendering:
    Qt Code:
    1. QImage AWidget::paint()
    2. {
    3. if (!visible())
    4. {
    5. cHasChange = false;
    6. return QImage();
    7. }
    8. if (!hasChange())
    9. {
    10. cHasChange = false;
    11. if (cLastImage != 0)
    12. {
    13. return *cLastImage;
    14. }
    15. }
    16. cHasChange = false;
    17.  
    18. short w = width();
    19. short h = height();
    20. short radTL = 10;
    21. short radTR = 10;
    22. short radBR = 10;
    23. short radBL = 10;
    24.  
    25. QBrush bg(QColor(100, 200, 100, 100));
    26.  
    27. QColor b(0, 0, 0, 255);
    28.  
    29. short wB = 1;
    30.  
    31.  
    32. if (cHasStyle)
    33. {
    34. if (cBorder->radius()->isValid())
    35. {
    36. radTL = cBorder->radius()->tl();
    37. radTR = cBorder->radius()->tr();
    38. radBR = cBorder->radius()->br();
    39. radBL = cBorder->radius()->bl();
    40. }
    41. if (cBackground->color()->isValid())
    42. {
    43. bg = QBrush(cBackground->color()->toQColor());
    44. }
    45. else if (cBackground->gradient()->isValid())
    46. {
    47. bg = QBrush(cBackground->gradient()->toQGradient());
    48. }
    49. if (cBorder->color()->isValid())
    50. {
    51. b = (cBorder->color()->toQColor());
    52. }
    53. if (cBorder->size()->isValid())
    54. {
    55. wB = cBorder->size()->left();
    56. }
    57. }
    58.  
    59. bool useCubic = false;
    60.  
    61. path.moveTo(radTL, 0);
    62. path.lineTo(w - radTR, 0);
    63. if (radTR > 0)
    64. {
    65. if (useCubic)
    66. {
    67. path.cubicTo(w, 0, w, radTR, w, radTR);
    68. }
    69. else
    70. {
    71. path.arcTo(w - radTR * 2, 0, radTR * 2, radTR * 2, 90, -90);
    72. }
    73. }
    74. path.lineTo(w, h - radBR);
    75. if (radBR > 0)
    76. {
    77. if (useCubic)
    78. {
    79. path.cubicTo(w, h, w - radBR, h, w - radBR, h);
    80. }
    81. else
    82. {
    83. path.arcTo(w - radBR * 2, h - radBR * 2, radBR * 2, radBR * 2, 0, -90);
    84. }
    85. }
    86. path.lineTo(radBL, h);
    87. if (radBL > 0)
    88. {
    89. if (useCubic)
    90. {
    91. path.cubicTo(0, h, 0, h - radBL, 0, h - radBL);
    92. }
    93. else
    94. {
    95. path.arcTo(0, h - radBL * 2, radBL * 2, radBL * 2, -90, -90);
    96. }
    97. }
    98. path.lineTo(0, radTL);
    99. if (radTL > 0)
    100. {
    101. if (useCubic)
    102. {
    103. path.cubicTo(0, radTL, 0, 0, radTL, 0);
    104. }
    105. else
    106. {
    107. path.arcTo(0, 0, radTL * 2, radTL * 2, -180, -90);
    108. }
    109. }
    110. path.closeSubpath();
    111.  
    112.  
    113. QImage *img = new QImage(w, h, QImage::Format_ARGB32);
    114. img->fill(0);
    115. QPainter painter;
    116. painter.begin(img);
    117. painter.setRenderHints(QPainter::Antialiasing);
    118. painter.setPen(QPen(b, wB, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
    119. painter.setBrush(bg);
    120.  
    121. painter.drawPath(path);
    122.  
    123. paintEvent(&painter);
    124.  
    125. // +++ draw children
    126. if (children().length() > 0)
    127. {
    128. for (int i = 0; i < children().length(); i++)
    129. {
    130. painter.drawImage(child(i)->x(), child(i)->y(), child(i)->paint());
    131. }
    132. }
    133. // --- draw children
    134.  
    135. painter.end();
    136.  
    137. cLastImage = img;
    138.  
    139. return *img;
    140. }
    To copy to clipboard, switch view to plain text mode 

    Furthermore would I like to ask, what the better way to render the border radius is - an arc or a bezier curve?

    If some information is missing, feel free to tell.

    cheers

  2. #2
    Join Date
    May 2010
    Location
    Germany
    Posts
    9
    Thanks
    1
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: QPainter Antialiasing for QImage

    I fixed the problem.
    I just had to seperate the rendering of the corners and the sides and set the pen width to half the width of the one for the sides.

    Thread can be closed.

Similar Threads

  1. initializing QPainter with a QImage
    By Aayush in forum Qt Programming
    Replies: 3
    Last Post: 20th October 2011, 12:47
  2. QPainter(&QPrinter) & QPainter(&QImage) communication
    By gufeatza in forum Qt Programming
    Replies: 2
    Last Post: 2nd February 2010, 07:25
  3. Replies: 5
    Last Post: 7th September 2009, 20:57
  4. QImage antialiasing
    By bunjee in forum Qt Programming
    Replies: 1
    Last Post: 5th June 2008, 19:37
  5. QPainter and QImage
    By beerkg in forum Newbie
    Replies: 3
    Last Post: 7th September 2006, 14:48

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.