QT实现圆形头像

xsjcoder 2014-03-10 03:04:55
最近在研究QT,想做一个类似YY的好友列表,好友的头像是圆形的。

利用setmask做过两种尝试,都存在锯齿问题:
1.利用圆形透明PNG的MASK做透明通道;
2.自定义QRegion;
结果1中的效果可能要相对比2中好一些,但是锯齿问题仍然不能很好解决。

想问问大家还有没有其他办法能实现这样的圆形头像,或者有什么办法能解决锯齿问题,谢谢。
...全文
562 点赞 收藏 25
写回复
25 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
Lankin2013 2015-12-23
引用 24 楼 ganhuanghuang 的回复:
[quote=引用 23 楼 lingyun0 的回复:] 困扰了很久,终于解决了,亲测可用。谢谢。 painter->setRenderHints(QPainter::SmoothPixmapTransform);//消锯齿 后面使用drawPixmap绘图。 (蒙板图片设成圆的就可以画圆了,我是画的圆角) 基本逻辑: (1) painter->setRenderHints(QPainter::SmoothPixmapTransform);//消锯齿 (2) QBitmap maskImage("Resources/images/icon/ic_portrait_mask_90x90.png"); //蒙板图片 QSize iconSize = icon.size(); icon = icon.scaled(QSize(90,90)); icon.setMask(maskImage); (3) painter->drawPixmap(iconRect,icon); 蒙板图片:
能否提供实现具体代码。我刚学,遇到这个问题,比较捉急[/quote] 上面贴的不就是具体代码么,原谅我一年之后才再次回来。。。
回复
ganhuanghuang 2014-10-27
引用 23 楼 lingyun0 的回复:
困扰了很久,终于解决了,亲测可用。谢谢。 painter->setRenderHints(QPainter::SmoothPixmapTransform);//消锯齿 后面使用drawPixmap绘图。 (蒙板图片设成圆的就可以画圆了,我是画的圆角) 基本逻辑: (1) painter->setRenderHints(QPainter::SmoothPixmapTransform);//消锯齿 (2) QBitmap maskImage("Resources/images/icon/ic_portrait_mask_90x90.png"); //蒙板图片 QSize iconSize = icon.size(); icon = icon.scaled(QSize(90,90)); icon.setMask(maskImage); (3) painter->drawPixmap(iconRect,icon); 蒙板图片:
能否提供实现具体代码。我刚学,遇到这个问题,比较捉急
回复
Lankin2013 2014-05-16
困扰了很久,终于解决了,亲测可用。谢谢。
painter->setRenderHints(QPainter::SmoothPixmapTransform);//消锯齿
后面使用drawPixmap绘图。
(蒙板图片设成圆的就可以画圆了,我是画的圆角)

基本逻辑:
(1) painter->setRenderHints(QPainter::SmoothPixmapTransform);//消锯齿

(2) QBitmap maskImage("Resources/images/icon/ic_portrait_mask_90x90.png"); //蒙板图片
QSize iconSize = icon.size();
icon = icon.scaled(QSize(90,90));
icon.setMask(maskImage);

(3) painter->drawPixmap(iconRect,icon);
蒙板图片:
回复
zhanglyl 2014-03-12
建议 多 看看 QT 自带的demo和examples的实例代码吧。
回复
zhanglyl 2014-03-12
为什么不使用PNG格式的图像,透明背景,直接显示,一行代码都不用,setMask做什么???
回复
xsjcoder 2014-03-11
这个帐号的博客莫名被封了,忘了注册邮箱,打算换个号重新开始,谢谢两位,散分结贴。
回复
xsjcoder 2014-03-10
引用 18 楼 JiMoKuangXiangQu 的回复:
[quote=引用 17 楼 xsjcoder 的回复:] [quote=引用 16 楼 JiMoKuangXiangQu 的回复:] [quote=引用 15 楼 zhao4zhong1 的回复:] [quote=引用 13 楼 JiMoKuangXiangQu 的回复:] 可能需要 QPainter::SmoothPixmapTransform 特性或者 HighQualityAntialiasing 。
QT高人来了!膜拜一下。[/quote] 这个,真是 菜鸟一枚![/quote] 如果用QPainter::SmoothPixmapTransform的话,那么设置图片就是用drawPixmap了吧,有方法绘圆形吗?文档的接口好像只支持矩形,不知道理解的有没有错。[/quote] 这个倒是没关系,图片做成矩形,不要的区域透明就好了。至于图片边缘的光滑度,虽然和上面提到的特性设置有 关系,但也和做的图片本身有关系。如果图片中间的圆圈本身就很大的锯齿,那么即使开了这些特性也是无济于事的。[/quote] 如果是这样的话那我就没必要再尝试这种方法了,我希望头像应该要支持各种普通的图片,如果刻意去做的透明效果图片,setmask也能很完美的展示。还是很感谢帮忙
回复
JiMoKuangXiangQu 2014-03-10
引用 17 楼 xsjcoder 的回复:
[quote=引用 16 楼 JiMoKuangXiangQu 的回复:] [quote=引用 15 楼 zhao4zhong1 的回复:] [quote=引用 13 楼 JiMoKuangXiangQu 的回复:] 可能需要 QPainter::SmoothPixmapTransform 特性或者 HighQualityAntialiasing 。
QT高人来了!膜拜一下。[/quote] 这个,真是 菜鸟一枚![/quote] 如果用QPainter::SmoothPixmapTransform的话,那么设置图片就是用drawPixmap了吧,有方法绘圆形吗?文档的接口好像只支持矩形,不知道理解的有没有错。[/quote] 这个倒是没关系,图片做成矩形,不要的区域透明就好了。至于图片边缘的光滑度,虽然和上面提到的特性设置有 关系,但也和做的图片本身有关系。如果图片中间的圆圈本身就很大的锯齿,那么即使开了这些特性也是无济于事的。
回复
xsjcoder 2014-03-10
引用 16 楼 JiMoKuangXiangQu 的回复:
[quote=引用 15 楼 zhao4zhong1 的回复:] [quote=引用 13 楼 JiMoKuangXiangQu 的回复:] 可能需要 QPainter::SmoothPixmapTransform 特性或者 HighQualityAntialiasing 。
QT高人来了!膜拜一下。[/quote] 这个,真是 菜鸟一枚![/quote] 如果用QPainter::SmoothPixmapTransform的话,那么设置图片就是用drawPixmap了吧,有方法绘圆形吗?文档的接口好像只支持矩形,不知道理解的有没有错。
回复
JiMoKuangXiangQu 2014-03-10
引用 15 楼 zhao4zhong1 的回复:
[quote=引用 13 楼 JiMoKuangXiangQu 的回复:] 可能需要 QPainter::SmoothPixmapTransform 特性或者 HighQualityAntialiasing 。
QT高人来了!膜拜一下。[/quote] 这个,真是 菜鸟一枚!
回复
赵4老师 2014-03-10
引用 13 楼 JiMoKuangXiangQu 的回复:
可能需要 QPainter::SmoothPixmapTransform 特性或者 HighQualityAntialiasing 。
QT高人来了!膜拜一下。
回复
xsjcoder 2014-03-10
引用 13 楼 JiMoKuangXiangQu 的回复:
可能需要 QPainter::SmoothPixmapTransform 特性或者 HighQualityAntialiasing 。
恩,可能需要再细看一下,之前只是做了简单的尝试,谢啦。
回复
JiMoKuangXiangQu 2014-03-10
可能需要 QPainter::SmoothPixmapTransform 特性或者 HighQualityAntialiasing 。
回复
JiMoKuangXiangQu 2014-03-10
引用 11 楼 xsjcoder 的回复:
[quote=引用 10 楼 JiMoKuangXiangQu 的回复:]
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing, true);
draw(&painter);
供参考。
之前尝试过,貌似只对绘图的去锯齿有用,对显示圆形图片的锯齿貌似不管用。是这样吗?[/quote] 应该不会。 http://qt-project.org/doc/qt-4.8/qpainter.html 在上面页面里面搜索 "Rendering Quality" 关键字,参看自己的代码,看是不是对该特性有误用。
回复
xsjcoder 2014-03-10
引用 10 楼 JiMoKuangXiangQu 的回复:
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing, true);
draw(&painter);
供参考。
之前尝试过,貌似只对绘图的去锯齿有用,对显示圆形图片的锯齿貌似不管用。是这样吗?
回复
JiMoKuangXiangQu 2014-03-10
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing, true);
draw(&painter);
供参考。
回复
xsjcoder 2014-03-10
引用 8 楼 zhao4zhong1 的回复:
只是我不了解QT。 可能你不必放弃用QT自带的绘图功能。
在没有更好办法之前值得一试,QT那边我找了一天都没找到效果比较好的方法。
回复
赵4老师 2014-03-10
只是我不了解QT。 可能你不必放弃用QT自带的绘图功能。
回复
xsjcoder 2014-03-10
引用 5 楼 zhao4zhong1 的回复:
#include <windows.h>
#include <gdiplus.h>
using namespace Gdiplus;
#pragma comment(lib, "gdiplus.lib")
VOID OnPaint(HDC hdc) {
   Graphics     graphics(hdc);
   Pen          pen(Color(255, 0, 0, 255));
   FontFamily   fontFamily(L"宋体");
   Font         font(&fontFamily, 12, FontStyleRegular, UnitPixel);
   PointF       pointF1(30.0f, 60.0f),pointF2(230.0f, 60.0f);
   SolidBrush   solidBrush(Color(255, 0, 0, 255));
   StringFormat stringFormat;
   WCHAR testString[] = L"Hello034∠你好";

   stringFormat.SetFormatFlags(StringFormatFlagsDirectionVertical);

   graphics.SetSmoothingMode(SmoothingModeDefault);
   graphics.DrawLine(&pen, 0, 0, 200, 100);
   graphics.DrawEllipse(&pen, 10, 10, 190, 90);
   graphics.SetTextRenderingHint(TextRenderingHintSystemDefault);
   graphics.DrawString(testString, -1, &font, pointF1, &stringFormat, &solidBrush);


   graphics.SetSmoothingMode(SmoothingModeHighQuality);
   graphics.DrawLine(&pen, 200, 0, 400, 100);
   graphics.DrawEllipse(&pen, 210, 10, 190, 90);
   graphics.SetTextRenderingHint(TextRenderingHintAntiAlias);
   graphics.DrawString(testString, -1, &font, pointF2, &stringFormat, &solidBrush);
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
   HDC          hdc;
   PAINTSTRUCT  ps;

   switch(message) {
   case WM_PAINT:
      hdc = BeginPaint(hWnd, &ps);
      OnPaint(hdc);
      EndPaint(hWnd, &ps);
      return 0;
   case WM_DESTROY:
      PostQuitMessage(0);
      return 0;
   default:
      return DefWindowProc(hWnd, message, wParam, lParam);
   }
}
INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, PSTR, INT iCmdShow) {
   HWND                hWnd;
   MSG                 msg;
   WNDCLASS            wndClass;
   GdiplusStartupInput gdiplusStartupInput;
   ULONG_PTR           gdiplusToken;

   GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

   wndClass.style          = CS_HREDRAW | CS_VREDRAW;
   wndClass.lpfnWndProc    = WndProc;
   wndClass.cbClsExtra     = 0;
   wndClass.cbWndExtra     = 0;
   wndClass.hInstance      = hInstance;
   wndClass.hIcon          = LoadIcon(NULL, IDI_APPLICATION);
   wndClass.hCursor        = LoadCursor(NULL, IDC_ARROW);
   wndClass.hbrBackground  = (HBRUSH)GetStockObject(WHITE_BRUSH);
   wndClass.lpszMenuName   = NULL;
   wndClass.lpszClassName  = TEXT("GettingStarted");

   RegisterClass(&wndClass);

   hWnd = CreateWindow(
      TEXT("GettingStarted"),   // window class name
      TEXT("Getting Started"),  // window caption
      WS_OVERLAPPEDWINDOW,      // window style
      CW_USEDEFAULT,            // initial x position
      CW_USEDEFAULT,            // initial y position
      CW_USEDEFAULT,            // initial x size
      CW_USEDEFAULT,            // initial y size
      NULL,                     // parent window handle
      NULL,                     // window menu handle
      hInstance,                // program instance handle
      NULL);                    // creation parameters

   ShowWindow(hWnd, iCmdShow);
   UpdateWindow(hWnd);

   while(GetMessage(&msg, NULL, 0, 0)) {
      TranslateMessage(&msg);
      DispatchMessage(&msg);
   }

   GdiplusShutdown(gdiplusToken);

   return 0;
}
您的意思是放弃QT自带的绘图自己用GDI绘制圆形头像是吧,晚上回去试试,先谢啦。
回复
赵4老师 2014-03-10
QT没弄过。 坐等楼下高人……
回复
加载更多回复
相关推荐
发帖
工具平台和程序库
创建于2007-09-28

2.4w+

社区成员

C/C++ 工具平台和程序库
申请成为版主
帖子事件
创建了帖子
2014-03-10 03:04
社区公告
暂无公告