动态

详情 返回 返回

qml實現頭像裁剪功能 - 动态 详情

效果

首先了解一下flickable

flickable在確定高度寬度後,使用contentWidth,contentHeight綁定內容大小,當內容大小大於flickable大小時,flickable會自動提供滾動條以便鼠標拖動查看。

所以打開一個圖片後要先調整適合flickable,前提是保持比例,不然根據圖片的比例縮放.
假設flickable是一個正方形,如果圖片長寬比為1:2等,那麼就要把長縮放為flickable的寬,寬按原比例縮放

width: Math.abs((implicitHeight-implicitWidth)/implicitWidth)<0.2?flickable.width:(implicitHeight>implicitWidth?flickable.width:implicitWidth*flickable.height/implicitHeight);
height: Math.abs((implicitHeight-implicitWidth)/implicitWidth)<0.2?flickable.height:(implicitHeight<implicitWidth?flickable.height:implicitHeight*flickable.width/implicitWidth);

implicitWidth指圖片的原始寬度(即Image控件不設置長度寬度時的默認長寬)

放縮的話可以通過增加減少image的width和height

繪製選擇圓框

填充flickable半透明黑,再挖去內切圓

        Canvas
        {
            id: canvas
            //覆蓋flickable
            anchors.fill: flickable;
            height: window.width;//創建的窗口大小
            onPaint: {
                var ctx = getContext("2d");
                ctx.fillStyle="rgba(0,0,0,0.5)";
                ctx.fillRect(0,0,width,height);//覆蓋透明黑

                ctx.globalCompositeOperation = "qt-clear";//該模式下將會從原圖像除去繪製的內容
                ctx.beginPath();
                ctx.arc(width / 2, height / 2, width/2, 0, 2 * Math.PI);//圓心x,圓心y,半徑,開始,結束角度
                ctx.fill();
            }
        }

如何截取

我的方法是按鈕按下loader加載component執行函數
首先flickable內部有內容時,會以內容建立座標系,左上角為原點,flickable.contentX就是flickable左上角在內容上的x座標(會隨移動而改變)

由於顯示的圖像是縮放過的,所有flickable在縮放後的圖像的x座標實際上是原圖中
flickable.contentX/scaleX
property double scaleX: image.width/image.implicitWidth;(放縮比)
drawImage後面4個參數是在canvas上的矩形區域繪製

完成後toDataURL()返回圖片base64數據(該數據可以轉為字符串,且可以直接用於存儲和image的source)

        Loader
        {
            id:loader;
            anchors.fill: flickable;
            visible: false;
        }

        Component
        {
            id:com;
            Canvas
            {
                renderTarget: Canvas.Image;
                property double scaleX: image.width/image.implicitWidth;

                property double scaleY: image.height/image.implicitHeight;
                width: flickable.width;
                height: flickable.height;

                onPaint:
                {
                    var ctx = getContext("2d");

                    //截取可視部分
                    ctx.drawImage(image,flickable.contentX/scaleX , flickable.contentY/scaleY, flickable.width/scaleX, flickable.height/scaleY, 0, 0, flickable.width, flickable.height);
            
                    changeSig(toDataURL());
                    close();
                }
            }
        }
user avatar mengps 头像
点赞 1 用户, 点赞了这篇动态!
点赞

Add a new 评论

Some HTML is okay.