65.9K
CodeProject 正在变化。 阅读更多。
Home

可缩放和可滚动图片框的应用

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.07/5 (12投票s)

2008 年 8 月 18 日

CPOL

2分钟阅读

viewsIcon

44745

downloadIcon

2021

测试新的图像插值算法。

引言

有很多图像放大方法。这个程序是为了测试一个新开发的图像插值算法而编写的。

如何使用这个程序

要使用这个程序,首先需要使用“打开”按钮打开一张图片。打开你选择的图片后,它将出现在左侧的PictureBox中。在这个PictureBox中,你会看到一个白色矩形。这显示了原始图片中显示在右侧PictureBox的部分。右侧PictureBox中的图片可以使用缩放滑块进行调整大小。你还可以使用清晰度滑块来调整清晰度,使图片更清晰。在获得所需的缩放和适当的清晰度后,使用“保存”按钮保存图片。缩放比例越大,所需时间越长。新保存的放大图片将具有更清晰的结果,但仍然保留原始细节。

关于这个程序

这个程序包括可缩放和可滚动的PictureBox,该PictureBox在CodeProject上有描述。一些成员建议这个用户控件应该包括图像的裁剪和选择功能。我考虑了这些建议,并编写了这个程序。在这个程序中,我为可缩放和可滚动的PictureBox控件添加了一个属性

Selection selection;

public Selection Selection
{
    get { return selection; }
    set { selection = value; Invalidate(); }
}

和两个公共方法

public Point ConvertControlPointToCanvas(Point point)
{
    Point pt = new Point();
    if (viewRectWidth > canvasSize.Width * zoom)
    {
        pt.X = (int)((float)(point.X - viewRectWidth / 2 + 
                canvasSize.Width * zoom / 2f) / zoom);
        pt.X = Math.Min(Math.Max(pt.X, 1), canvasSize.Width - 1);
    }
    else pt.X = (int)((float)(point.X + hScrollBar1.Value) / zoom);
    if (viewRectHeight > canvasSize.Height * zoom)
    {
        pt.Y = (int)((float)(point.Y - viewRectHeight / 2 + 
                canvasSize.Height * zoom / 2f) / zoom);
        pt.Y = Math.Max(Math.Min(pt.Y, canvasSize.Height - 1), 1);
    }
    else pt.Y = (int)((float)(point.Y + vScrollBar1.Value) / zoom);
    return pt;
}

public Point ConvertCanvasPointToControl(Point point)
{
    float xOffset = viewRectWidth > canvasSize.Width * zoom ? 
          (viewRectWidth - canvasSize.Width * zoom) / 2f : -hScrollBar1.Value;
    float yOffset = viewRectHeight > canvasSize.Height * zoom ? 
          (viewRectHeight - canvasSize.Height * zoom) / 2f : -vScrollBar1.Value;
    Matrix mxCanvastoContol = new Matrix();
    mxCanvastoContol.Scale(zoom, zoom);
    mxCanvastoContol.Translate(xOffset, yOffset, MatrixOrder.Append);
    Point[] pts = new Point[] { point };
    mxCanvastoContol.TransformPoints(pts);
    return pts[0];
}

我还编写了一个类selection.cs用于Selection属性

using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;


namespace YLScsZoom
{
    public class Selection
    {
        Color lineColor = Color.Black;
        float lineWidth = 1.0f;

        Point location = new Point(0, 0);
        Size size = new Size(0, 0);

        public Color LineColor
        {
            get { return lineColor; }
            set { lineColor = value; }
        }

        public float LineWidth
        {
            get { return lineWidth; }
            set { lineWidth = value; }
        }

        public Size Size
        {
            get { return size; }
            set { size = value; }
        }

        public Point Location
        {
            get { return location; }
            set { location = value; }
        }

        public void Draw(Graphics g)
        {
            Pen p = new Pen(lineColor, lineWidth);
            g.DrawRectangle(p, new Rectangle(location, size));
            p.Dispose();
        }

        public virtual bool isHitting(Point pt)
        {
            Rectangle r = new Rectangle(location, size);
            if (r.Contains(pt))
                return true;
            else return false;
        }
    }
}

你可以通过其属性LocationSize使用selection选择图像。在这个程序中,我使用了控件的鼠标事件来获取控件中的点,然后使用方法ConvertControlPointToCanvas将其转换为图像,即选择的Location。选择的Size由缩放比例和显示放大图像的客户端窗口的大小决定。

这个程序中使用的图像插值方法与Libor Tinka提到的方法完全不同。我的方法有两个参数:缩放比例和清晰度比例。

using System;
using System.Drawing;

namespace YLScsLib.Imaging
{
    public class YLScsZoom
    {
        public YLScsZoom();

        public static Bitmap Apply(Bitmap srcBmp, float zoom);
        public static Bitmap Apply(Bitmap srcBmp, float zoom, float factor);
        public static byte[,] Apply(byte[,] srcBytes, 
               int nwidth, int nheight, float factor);
        public static ChannelBytes Apply(ChannelBytes srcBytes, 
               int nwidth, int nheight, float factor);
    }
}

这两个值由这个程序中的两个滑块提供。

谢谢

非常感谢你尝试这个程序和我的图像插值算法。

© . All rights reserved.