发现有些小程序设置头像的处理似乎有点问题,特别是不断的放大、缩小后,会出现图片只显示出一半。主要问题是这些程序对于图片的边界判断存在问题,从而导致一些问题。
本文主要实现WPF下用户头像的设置处理,实现功能是用户选择一张图片该例子可以对选择的图片进行缩放和移动操作,最后方块内的部分,会被裁剪出来,最后以圆形头像显示出来。

启动后初始画面如下所示:

点击设置头像后,会显示对话框,点击导入按钮,选择好自己想要设置的图片,如下所示,可以用鼠标左键选中图片进行移动,使用滚轮进行图片的缩放。
设置好自己满意的图片后,点击ok即可。初始加载的图片,程序会等比缩放图片,让其完全的填充200×200这么大正方形区域,进行放大时,是以正方形的中心进行放大,
而缩小时,优先采用中心进行缩小,当某个边的尺寸快要不足,不能再以中心缩放,则以那一条边作为基准进行缩放,从而提高了用户的友好交互。


主要的代码如下,边界判断的思路是共通的,用其他语言写这样的程序,也得进行这样的判断。
移动图片时的处理逻辑

private void editingPhoto_MouseMove(object sender, MouseEventArgs e)  
{  
    if (this.isMouseLeftButtonDown)  
    {  
        Point position = e.GetPosition(this.editingPhoto);  
        TranslateTransform transform = tlt;  
  
        double targetX = transform.X + (position.X - this.previousMousePoint.X);  
        double targetY = transform.Y + (position.Y - this.previousMousePoint.Y);  
        double targetScaleX = sfr.ScaleX;  
        double targetScaleY = sfr.ScaleY;  
  
        //If move the border will display on canvas  
        if (CENTER_CIRCLE_RADIUS * targetScaleX - targetX < CENTER_CIRCLE_RADIUS ||  
            (this.editingPhoto.ActualWidth - CENTER_CIRCLE_RADIUS) * targetScaleX + targetX < CENTER_CIRCLE_RADIUS)  
        {  
        }  
        else  
        {  
            transform.X = targetX;  
        }  
  
        // If move the border will display on canvas  
        if (CENTER_CIRCLE_DIAMETER * targetScaleY / 2 - targetY < CENTER_CIRCLE_RADIUS ||  
            (this.editingPhoto.ActualHeight - CENTER_CIRCLE_RADIUS) * targetScaleY + targetY < CENTER_CIRCLE_RADIUS)  
        {  
        }  
        else  
        {  
            transform.Y = targetY;  
        }  
        this.previousMousePoint = position;  
    }  
} 

图片缩小时的处理逻辑

 

private void ZoomInImage(double newScaleValue)  
{  
    if (newScaleValue <= 1)  
    {  
        return;  
    }  
  
    double targetX = tlt.X;  
    double targetY = tlt.Y;  
  
    if (newScaleValue * this.editingPhoto.ActualWidth + tlt.X < CENTER_CIRCLE_DIAMETER ||  
        newScaleValue * this.editingPhoto.ActualHeight + tlt.Y < CENTER_CIRCLE_DIAMETER)  
    {  
        return;  
    }  
  
    // image left boder will display in canvas   
    if (CENTER_CIRCLE_RADIUS * newScaleValue - targetX < CENTER_CIRCLE_RADIUS)  
    {  
        // image right boder will display in canvas  
        if ((this.editingPhoto.Width - CENTER_CIRCLE_RADIUS) * newScaleValue + targetX < CENTER_CIRCLE_RADIUS)  
        {  
            // The left boder and right both display in canvas means the image size is ltter than the minamize size, return  
            return;  
        }  
        // the image right border still not display in canvas, so it will zoomin and then move left the image.  
        else  
        {  
            // X = Radius * Scale - Radius;                              
            targetX = (CENTER_CIRCLE_RADIUS) * (newScaleValue - 1);  
        }  
    }  
    // the image left border not display in canvas  
    else  
    {  
        //If zoom in, the image right border display in canvas, so it will zoomin and then move right the image.  
        if ((this.editingPhoto.ActualWidth - CENTER_CIRCLE_RADIUS) * newScaleValue + targetX < CENTER_CIRCLE_RADIUS)  
        {  
            // X = (ActualWidth - Radius) * Scale - Radius;  
            targetX = (-1) * ((this.editingPhoto.ActualWidth - CENTER_CIRCLE_RADIUS) * newScaleValue - CENTER_CIRCLE_RADIUS);  
        }  
        //the image  border nod display in canvas, zoom in. No need to move image.  
        else  
        {  
        }  
    }  
  
  
    // the image top border will display in canvas.   
    if (CENTER_CIRCLE_RADIUS * newScaleValue - targetY < CENTER_CIRCLE_RADIUS)  
    {  
        // the image bottom border will display in canvas.  
        if ((this.editingPhoto.ActualHeight - CENTER_CIRCLE_RADIUS) * newScaleValue + targetY < CENTER_CIRCLE_RADIUS)  
        {  
            //The top border and bottom border both display in canvas means the image size is letter than the minamize size, so return.  
            return;  
        }  
        // the image bottom border still not display in canvas, so it will zoomin and then move up the image.  
        else  
        {  
            // Y = Radius * Scale - Radius;                              
            targetY = (CENTER_CIRCLE_RADIUS) * (newScaleValue - 1);  
        }  
    }  
    //the image top border not display in canvas  
    else  
    {  
        //the image botton border display in canvas, so it will zoomin and then move down the image.  
        if ((this.editingPhoto.ActualHeight - CENTER_CIRCLE_RADIUS) * newScaleValue + targetY < CENTER_CIRCLE_RADIUS)  
        {  
            // Y = (ActualHeight - Radius) * Scale - Radius;  
            targetY = (-1) * ((this.editingPhoto.ActualHeight - CENTER_CIRCLE_RADIUS) * newScaleValue - CENTER_CIRCLE_RADIUS);  
        }  
        //the image bottom border not display in canvas, zoom in. No need to move image.  
        else  
        {  
        }  
    }  
  
    sfr.CenterX = CENTER_CIRCLE_RADIUS;  
    sfr.CenterY = CENTER_CIRCLE_RADIUS;  
    sfr.ScaleX = newScaleValue;  
    sfr.ScaleY = newScaleValue;  
  
    tlt.X = targetX;  
    tlt.Y = targetY;  
} 

 完整代码上传到此了:http://download.csdn.net/detail/u013376417/8417509

发表评论

电子邮件地址不会被公开。 必填项已用*标注

Post Navigation