对于圆角图片处理,主要使用了四种办法来实现
1.Qt里面使用QPainter来画个
2.QML里面使用opengles来渲染
3.使用原始图片和备用图片来合成
4.使用QML-Canvas来渲染
发现前两种无论如何画出来的还是有些锯齿,虽然设置了抗锯齿,效果不明显
第三种,图片合成,主要是采用图片与图片的z值来产生那种效果,但是一旦换肤就显而易见的有问题
第四种比较满意,效果还不错
先说第一种:
代码:
void YibanImage::paintEvent(QPaintEvent *) { QPainter painter(this); painter.setPen(Qt::gray); painter.setRenderHint (QPainter::HighQualityAntialiasing,true); painter.drawEllipse(0, 0, 52, 52); QPixmap icon(currentFileName); QImage fixedImage(52, 52, QImage::Format_ARGB32_Premultiplied); fixedImage.fill(0); // Make sure you don't have garbage in there QPainter imgPainter(&fixedImage); QPainterPath clip; clip.addEllipse(0, 0, 52, 52); // this is the shape we want to clip to imgPainter.setRenderHint(QPainter::HighQualityAntialiasing,true); imgPainter.setClipPath(clip); imgPainter.drawPixmap(0, 0, 52, 52, icon); imgPainter.end(); painter.drawPixmap(0, 0, 52, 52, QPixmap::fromImage(fixedImage)); }设置了高质量抗锯齿,但是发现还是有锯齿,有心人可以修正,再此谢过
第二种:
import QtQuick 2.1 import "../openglTxt.js" as MyOpenglTxt /* ImageScope - Scope a Image * property string source * Image source * property real magnification * magnification of image (>0) * property int scopeX / scopeY * position of scope * property real radius * radius of scope * * ImageScope { * width: 50; height: 50 * source: "sample.img" * radius: width / 2 * scopeX: 30; scopeY: 20 * } */ Item { id: imgScope property real magnification: 1.0 property int scopeX: 0 property int scopeY: 0 property real radius: 0 // interImage aliases property alias fillMode: interImage.fillMode property alias horizontalAlignment: interImage.horizontalAlignment property alias mirror: interImage.mirror property alias paintedHeight: interImage.paintedHeight property alias paintedWidth: interImage.paintedWidth property alias progress: interImage.progress property alias smooth: interImage.smooth property alias source: interImage.source property alias sourceSize: interImage.sourceSize property alias status: interImage.status property alias verticalAlignment: interImage.verticalAlignment Image { id: interImage visible: false fillMode: Image.PreserveAspectFit width: sourceSize.width * magnification height: sourceSize.height * magnification antialiasing: true } ShaderEffect { id: effect anchors.fill: parent antialiasing: true implicitWidth: interImage.sourceSize.width implicitHeight: interImage.sourceSize.height property Image _image: interImage property real _w: width / interImage.width property real _h: height / interImage.height property real _rX: radius / interImage.width / _w property real _rY: radius / interImage.height / _h property real _cX: scopeX / interImage.width property real _cY: scopeY / interImage.height fragmentShader: MyOpenglTxt.openglStr } }opengles语句如下:
var openglStr = "varying highp vec2 qt_TexCoord0;\ uniform sampler2D _image; uniform lowp float qt_Opacity; uniform highp float _w; uniform highp float _h; uniform highp float _cX; uniform highp float _cY; uniform highp float _rX; uniform highp float _rY; // square float highp float sq(float a) { return a * a; } void main() { lowp float opacity = qt_Opacity; highp float x = qt_TexCoord0.x; highp float y = qt_TexCoord0.y; if(x <= _rX && y <= _rY && sq(x - _rX) / sq(_rX) + sq(y - _rY) / sq(_rY) > 1.0) opacity = 0.0; if(x <= _rX && y >= 1.0 - _rY && sq(x - _rX) / sq(_rX) + sq(y - 1.0 + _rY) / sq(_rY) > 1.0) opacity = 0.0; if(x >= 1.0 - _rX && y <= _rY && sq(x - 1.0 + _rX) / sq(_rX) + sq(y - _rY) / sq(_rY) > 1.0) opacity = 0.0; if(x >= 1.0 - _rX && y >= 1.0 - _rY && sq(x - 1.0 + _rX) / sq(_rX) + sq(y - 1.0 + _rY) / sq(_rY) > 1.0) opacity = 0.0; x = x * _w + _cX; y = y * _h + _cY; if(x < 0.0 || x > 1.0 || y < 0.0 || y > 1.0) opacity = 0.0; gl_FragColor = texture2D(_image, vec2(x, y)) * opacity; } "主要使用的opengles着色器来做,发现四周瑕疵万千,有心人可以修正
第三种不在此赘述,因为实际用不到
第四种:
import QtQuick 2.0 import QtQuick.Controls 1.1 import QtQuick.Window 2.0 import QtQuick.Controls.Styles 1.1 import QtGraphicalEffects 1.0 Item { id:mainRect width: 72 height: 72 property string canvasimg: "qrc:/image/mainui/4.png" property color mystroke: "#D74F37" Canvas { id: canvas width: parent.width; height: parent.height property real hue: 0.0 onPaint: { var ctx = getContext("2d") ctx.lineWidth = 4 // store current context setup ctx.save() ctx.strokeStyle = mystroke; ctx.beginPath() ctx.arc(mainRect.width/2, mainRect.height/2, mainRect.width/2, 0, Math.PI * 2, true); ctx.closePath() ctx.clip() // create clip from triangle path // draw image with clip applied ctx.drawImage(canvasimg, 0, 0) // draw stroke around path ctx.closePath() ctx.stroke() // restore previous setup ctx.restore() } Component.onCompleted: { loadImage(canvasimg) } } function repaintUI() { canvas.requestPaint(); } }
最后一个js方法就是使用Canvas的repaint方法,因为初始化的时候对其赋值,需要重新刷新一遍
基于以上四种方法,感觉第四种比较好点,能够成功应用于实际项目中,另外Canvas的语法也很蛋疼,对于html的Canvas要多少了解才能好处理