在 imagebox 控件中裁剪图像并保存

Posted

技术标签:

【中文标题】在 imagebox 控件中裁剪图像并保存【英文标题】:Crop an image in imagebox control and save it 【发布时间】:2013-07-08 07:16:31 【问题描述】:

我正在做一个程序来设计卡片并实时显示图像。我已经完成了那部分,它工作得很好。现在我需要裁剪图像并保存为它的保存方式,在顶部和底部有 2 个白条。这是我现在用来保存的代码。

        private void SaveCardbtn_Click(object sender, EventArgs e)
        
            //Open the saveFileDialog
            if (saveWork.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            
                CardImg.Image.Save(saveWork.FileName, ImageFormat.Jpeg);
            
        

谢谢。

【问题讨论】:

问题是什么? 问题是如何裁剪图像然后保存 【参考方案1】:

我已经在 asp .net 论坛上发布了这个答案。 请试试这个 -

以下裁剪函数将接受 4 个参数:

    Width:这将是裁剪图像的宽度。 Height:这将是裁剪图像的高度。 Source Image File Path:这将是源图像文件的完整路径。

    Save Cropped Image File Path:这将是保存裁剪图像文件的完整路径。

    public static void CropImage(int Width, int Height, string sourceFilePath, string saveFilePath) 
    // variable for percentage resize 
    float percentageResize = 0;
    float percentageResizeW = 0;
    float percentageResizeH = 0;
    
    // variables for the dimension of source and cropped image 
    int sourceX = 0;
    int sourceY = 0;
    int destX = 0;
    int destY = 0;
    
    // Create a bitmap object file from source file 
    Bitmap sourceImage = new Bitmap(sourceFilePath);
    
    // Set the source dimension to the variables 
    int sourceWidth = sourceImage.Width;
    int sourceHeight = sourceImage.Height;
    
    // Calculate the percentage resize 
    percentageResizeW = ((float)Width / (float)sourceWidth);
    percentageResizeH = ((float)Height / (float)sourceHeight);
    
    // Checking the resize percentage 
    if (percentageResizeH < percentageResizeW) 
        percentageResize = percentageResizeW;
        destY = System.Convert.ToInt16((Height - (sourceHeight * percentageResize)) / 2);
     else 
        percentageResize = percentageResizeH;
        destX = System.Convert.ToInt16((Width - (sourceWidth * percentageResize)) / 2);
    
    
    // Set the new cropped percentage image
    int destWidth = (int)Math.Round(sourceWidth * percentageResize);
    int destHeight = (int)Math.Round(sourceHeight * percentageResize);
    
    // Create the image object 
    using (Bitmap objBitmap = new Bitmap(Width, Height)) 
        objBitmap.SetResolution(sourceImage.HorizontalResolution, sourceImage.VerticalResolution);
        using (Graphics objGraphics = Graphics.FromImage(objBitmap)) 
            // Set the graphic format for better result cropping 
            objGraphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
            objGraphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
            objGraphics.DrawImage(sourceImage, new Rectangle(destX, destY, destWidth, destHeight), new Rectangle(sourceX, sourceY, sourceWidth, sourceHeight), GraphicsUnit.Pixel);
    
            // Save the file path, note we use png format to support png file 
            objBitmap.Save(saveFilePath, ImageFormat.Png);
            
        
    
    

使用以下代码调用上述CropImage方法:

CropImage(100, 100, "c://destinationimage.jpg", "c://newcroppedimage.jpg");

希望对您有所帮助!

【讨论】:

这很好,谢谢,只是希望我可以让它与 imagebox 一起工作【参考方案2】:

我使用此代码进行图像裁剪。请注意 pbOriginalImage 是你的图片框,里面有图片。

       private void pbOriginalImage_MouseDown(object sender, MouseEventArgs e)
    
        try
        
            // Starting point of the selection:
            if (e.Button == MouseButtons.Left)
            
                _selecting = true;
                _selection = new Rectangle(new Point(e.X, e.Y), new Size());
            
        
        catch (Exception ex)
        
            ApplicationExceptions.HandleAppExc(ex);
        
    

    private void pbOriginalImage_MouseMove(object sender, MouseEventArgs e)
    
        try
        
            // Update the actual size of the selection:
            if (_selecting)
            
                _selection.Width = e.X - _selection.X;
                _selection.Height = e.Y - _selection.Y;

                // Redraw the picturebox:
                pbOriginalImage.Refresh();
            
        
        catch (Exception ex)
        
            ApplicationExceptions.HandleAppExc(ex);
        

    

    private void pbOriginalImage_MouseUp(object sender, MouseEventArgs e)
    
        try
        
            if (pbOriginalImage.Image == null)
                return;

            if (e.Button == MouseButtons.Left && _selecting)
            
                // check selection rectangle has non-zero Height and Width
                if (!ValidateSelection(_selection))
                
                    _selecting = false;

                    return;
                

                // Check that selection rectangle does extend outside of image boundaries
                ValidateRectangleSize();

                // Create cropped image:
                Image tempImage = pbOriginalImage.Image.Clone() as Image;
                Image img = tempImage.Crop(_selection);



                // Fit image to the picturebox:
                profileImage.Image = img.Fit2PictureBox(profileImage);
                _selecting = false;
            
        
        catch (Exception ex)
        
            ApplicationExceptions.HandleAppExc(ex);
        

    

    private void pbOriginalImage_Paint(object sender, PaintEventArgs e)
    
        try
        
            if (_selecting)
            
                // Draw a rectangle displaying the current selection
                Pen pen = Pens.GreenYellow;
                e.Graphics.DrawRectangle(pen, _selection);
            
        
        catch (Exception ex)
        
            ApplicationExceptions.HandleAppExc(ex);
            throw;
        
    

    private void commandBrowse_Click(object sender, EventArgs e)
    
        try
        
            using (OpenFileDialog dlg = new OpenFileDialog())
            
                dlg.Filter = "JPG Files (*.jpg)|*.jpg|JPEG Files (*.jpeg)|*.jpeg|bmp Files (*.bmp)|*.bmp|PNG Files (*.png)|*.png|GIF Files (*.gif)|*.gif";
                if (dlg.ShowDialog() == DialogResult.OK)
                
                    FileInfo file = new FileInfo(dlg.FileName);

                    if (file.Length == 0)
                    
                        MessageBoxEx.Show("Invalid image. Please select valid image.", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Information);
                        return;
                    
                    else if (file.Length > 2097152)
                    
                        MessageBoxEx.Show("Image size cannot exceed 2MB.", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Information);
                        return;
                    
                    textProfileImagePath.Text = dlg.FileName;
                    pbOriginalImage.Image = Image.FromFile(dlg.FileName).Fit2PictureBox(pbOriginalImage);
                    profileImage.Image = Image.FromFile(dlg.FileName).Fit2PictureBox(profileImage);
                
            
        
        catch (Exception ex)
        
            if (ex.Message.Contains("Out of memory"))
            
                MessageBoxEx.Show("Invalid image. Please select valid image.", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Information);
            
            else
                ApplicationExceptions.HandleAppExc(ex);
        
    

    // Check that selection rectangle does extend outside of image boundaries
    private void ValidateRectangleSize()
    
        Size imgSize = this.pbOriginalImage.Image.Size;
        int selectionWidth;
        int selectionHeight;

        // check width
        if (_selection.X < 0)
        
            _selection.X = 0;
        

        selectionWidth = _selection.Width + _selection.X;
        if (selectionWidth > imgSize.Width)
        
            _selection.Width = imgSize.Width - _selection.X - 1;
        

        // check height
        if (_selection.Y < 0)
        
            _selection.Y = 0;
        

        selectionHeight = _selection.Height + _selection.Y;
        if (selectionHeight > imgSize.Height)
        
            _selection.Height = imgSize.Height - _selection.Y - 1;
        
    

    // check selection rectangle has non-zero Height and Width
    private bool ValidateSelection(Rectangle selection)
    
        // routine to validate the selection
        if (selection.Width <= 0 || selection.Height <= 0)
        
            // if you get here a good rectangle was not created
            return false;
        
        else
        
            return true;
        
    

这是我使用的扩展类。

     public static class ImageExtension

    /// <summary>
    /// Crops an image according to a selection rectangel
    /// </summary>
    /// <param name="image">
    /// the image to be cropped
    /// </param>
    /// <param name="selection">
    /// the selection
    /// </param>
    /// <returns>
    /// cropped image
    /// </returns>
    public static Image Crop(this Image image, Rectangle selection)
    
        Bitmap bmp = image as Bitmap;

        // Check if it is a bitmap:
        if (bmp == null)
            throw new ArgumentException("Not a valid image (Bitmap)");

        // Crop the image:
        Bitmap cropBmp = bmp.Clone(selection, bmp.PixelFormat);

        // Release the resources:
        image.Dispose();

        return cropBmp;
    
    //---------------------------------------------------------------------
    /// <summary>
    /// Fits an image to the size of a picturebox
    /// </summary>
    /// <param name="image">
    /// image to be fit
    /// </param>
    /// <param name="picBox">
    /// picturebox in that the image should fit
    /// </param>
    /// <returns>
    /// fitted image
    /// </returns>
    /// <remarks>
    /// Although the picturebox has the SizeMode-property that offers
    /// the same functionality an OutOfMemory-Exception is thrown
    /// when assigning images to a picturebox several times.
    /// 
    /// AFAIK the SizeMode is designed for assigning an image to
    /// picturebox only once.
    /// </remarks>
    public static Image Fit2PictureBox(this Image image, PictureBox picBox)
    
        Bitmap bmp = null;
        Graphics g;

        // Scale:
        double scaleY = (double)image.Width / picBox.Width;
        double scaleX = (double)image.Height / picBox.Height;
        double scale = scaleY < scaleX ? scaleX : scaleY;

        // Create new bitmap:
        bmp = new Bitmap(
            (int)((double)image.Width / scale),
            (int)((double)image.Height / scale));

        // Set resolution of the new image:
        bmp.SetResolution(
            image.HorizontalResolution,
            image.VerticalResolution);

        // Create graphics:
        g = Graphics.FromImage(bmp);

        // Set interpolation mode:
        g.InterpolationMode = InterpolationMode.HighQualityBicubic;

        // Draw the new image:
        g.DrawImage(
            image,
            new Rectangle(          // Ziel
                0, 0,
                bmp.Width, bmp.Height),
            new Rectangle(          // Quelle
                0, 0,
                image.Width, image.Height),
            GraphicsUnit.Pixel);

        // Release the resources of the graphics:
        g.Dispose();

        // Release the resources of the origin image:
        image.Dispose();

        return bmp;
    

【讨论】:

以上是关于在 imagebox 控件中裁剪图像并保存的主要内容,如果未能解决你的问题,请参考以下文章

捕获和裁剪图像并保存裁剪的图像

从文件夹中读取所有图像并检测人脸,裁剪并保存到新文件夹

裁剪图像并保存到 sdcard (Android) 中的特定文件夹?

从相机裁剪图像并保存

如何使用Swift选择图像的一部分,裁剪并保存?

HTML5 画布在非矩形部分裁剪并保存图像