c# - जूमेड इमेज कैसे बनाएं?



winforms bitmap (1)

आपको दो मुद्दों को संबोधित करने की आवश्यकता है:

  • संपूर्ण PictureBox.ClientArea बजाय वास्तविक Image Graphics क्षेत्र को क्लिप करें

  • माउस ईवेंट के निर्देशांक को वास्तविक छवि में स्केल करें जब उन्हें प्राप्त करना और रिकॉर्ड करना और फिर से Paint इवेंट में आकर्षित करने के लिए उनका उपयोग करें।

दोनों के लिए हमें Image के ज़ूम कारक को जानना होगा; कतरन के लिए हमें ImageArea को जानना होगा और ड्राइंग के लिए मैं बस दो माउस स्थानों को संग्रहीत करूंगा।

यहाँ कक्षा स्तर चर मैं उपयोग कर रहे हैं:

PointF mDown = Point.Empty;
PointF mLast = Point.Empty;
float zoom = 1f;
RectangleF ImgArea = RectangleF.Empty;

ध्यान दें कि मैं सभी के लिए floats उपयोग करता हूं, क्योंकि हमें कुछ विभाजन करने की आवश्यकता होगी।

पहले हम zoom और ImageArea गणना करेंगे:

void GetImageScaleData(PictureBox pbox)
{
    SizeF sp = pbox.ClientSize;
    SizeF si = pbox.Image.Size;
    float rp = 1f * sp.Width / sp.Height;   // calculate the ratios of
    float ri = 1f * si.Width / si.Height;   // pbox and image

    if (rp > ri)
    {
        zoom = sp.Height / si.Height;
        float width = si.Width * zoom;
        float left = (sp.Width - width) / 2;
        ImgArea = new RectangleF(left, 0, width, sp.Height);
    }
    else
    {
        zoom = sp.Width / si.Width;
        float height = si.Height * zoom;
        float top = (sp.Height - height) / 2;
        ImgArea = new RectangleF(0, top, sp.Width, height);
    }
}

इस Image को हर बार एक नई Image लोड होने और पिक्चरबॉक्स के किसी भी आकार बदलने पर भी कहा जाना चाहिए:

private void pictureBox1_Resize(object sender, EventArgs e)
{
    GetImageScaleData(pictureBox1);
}

अब नी को माउस स्थानों को स्टोर करना होगा। चूंकि उन्हें आकार बदलने के बाद पुन: प्रयोज्य होना चाहिए, इसलिए हमें उन्हें निर्देशांक में बदलने की आवश्यकता है। यह दिनचर्या वह कर सकती है और फिर से वापस भी:

PointF scalePoint(PointF pt, bool scale)
{
    return scale ? new PointF( (pt.X - ImgArea.X) / zoom, (pt.Y - ImgArea.Y) / zoom)
                 : new PointF( pt.X * zoom + ImgArea.X, pt.Y * zoom + ImgArea.Y);
}

अंत में हम Paint इवेंट को कोड कर सकते हैं

private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
    using (Pen pen = new Pen(Color.Fuchsia, 2.5f) { DashStyle = DashStyle.Dot})
        e.Graphics.DrawRectangle(pen, Rectangle.Round(ImgArea));

    e.Graphics.SetClip(ImgArea);
    e.Graphics.DrawLine(Pens.Red, scalePoint(mDown, false), scalePoint(mLast, false));
}

.. और माउस घटनाएँ:

private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
    mDown = scalePoint(e.Location, true);
}

private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
    if (e.Button == System.Windows.Forms.MouseButtons.Left)
    {
        mLast = scalePoint(e.Location, true);
        pictureBox1.Invalidate();
    }
}

अधिक जटिल आरेखण के लिए आप निर्देशांक को List<PointF> में संग्रहीत करेंगे और उन्हें वापस रूपांतरित करेंगे, बहुत ऊपर जैसा ..:

List<PointF> points = new List<PointF>();

और फिर:

e.Graphics.DrawCurve(Pens.Orange, points.Select(x => scalePoint(x, false)).ToArray());

मेरे पास मेरे आवेदन में Size 400X400 का एक पिक्चरबॉक्स है। SizeMode का SizeMode करके सेट किया Zoomed । मैंने पिक्चरबॉक्स में 700X446 की पीएनजी इमेज लोड की है।

मेरे पास निम्नलिखित समस्या है,

भले ही मैं लाल पथ के साथ एक काली सीधी रेखा खींच रहा हूं, वास्तव में इसे लोडेड छवि के साथ दिखाया जा रहा है।

मैं इस मुद्दे को कैसे हल कर सकता हूं?

PS मैं केवल चित्र पर चित्र बनाना चाहता हूं, न कि पूरा चित्रपट।

सोर्स कोड:

 public partial class MainForm : Form
 {
    Bitmap _inputImage = null;
    //Graphics _imageGraphics = null;

    #region ctor
    public MainForm()
    {
        InitializeComponent();

        _inputImage = Bitmap.FromFile(@"E:\cracked.png") as Bitmap;

        this.inputImagePictureBox.Image = _inputImage;
    }
    #endregion

    #region Mouse Up and Down
    Point _startPoint = Point.Empty;

    private void left_MouseDown(object sender, MouseEventArgs e)
    {
        if (e.Button == System.Windows.Forms.MouseButtons.Left)
        {
            _startPoint = e.Location;

            Circle tempCircle = new Circle(_startPoint, 10);

            Bitmap tempImage = (Bitmap)_inputImage.Clone();

            Graphics g = Graphics.FromImage(tempImage);

            tempCircle.Draw(g);

            inputImagePictureBox.Image = tempImage;
        }
    }

    private void pressed_MouseMove(object sender, MouseEventArgs e)
    {
        if (e.Button == System.Windows.Forms.MouseButtons.Left)
        {
            if (_startPoint != e.Location)
            {
                Line tempLine = new Line(_startPoint, e.Location);

                Bitmap tempImage = (Bitmap)_inputImage.Clone();

                Graphics g = Graphics.FromImage(tempImage);

                tempLine.Draw(g);

                inputImagePictureBox.Image = tempImage;
            }
        }
    }

    Bitmap _savedImage;

    private void left__MouseUp(object sender, MouseEventArgs e)
    {
        if (e.Button == System.Windows.Forms.MouseButtons.Left)
        {
            if (_startPoint != e.Location)
            {
                Line tempLine = new Line(_startPoint, e.Location);

                Bitmap tempImage = (Bitmap)_inputImage.Clone();

                Graphics g = Graphics.FromImage(tempImage);

                tempLine.Draw(g);

                _savedImage = tempImage;

                inputImagePictureBox.Image = tempImage;
            }
            else
            {
                Bitmap tempImage = (Bitmap)_inputImage.Clone();
                Graphics g = Graphics.FromImage(tempImage);

                inputImagePictureBox.Image = tempImage;
            }
        }
    } 
}




picturebox