【问题标题】:Cut a center of a image剪切图像的中心
【发布时间】:2015-04-09 19:47:00
【问题描述】:

假设我有一个 400x300px 的图像,我想在服务器端(C#、.NET 4.0)将其剪切为 200x200px 居中。

我该怎么做?使用一种画布并移动它?任何教程/代码示例/建议?

【问题讨论】:

标签: c# image image-processing


【解决方案1】:

试试这样的:

        Bitmap sourceImage = ...;

        int targetWidth = 200;
        int targetHeight = 200;

        int x = sourceImage.Width / 2 - targetWidth / 2;
        int y = sourceImage.Height / 2 - targetHeight / 2;

        Rectangle cropArea = 
            new Rectangle(x, y, targetWidth, targetHeight);

        Bitmap targetImage = 
            sourceImage.Clone(cropArea, sourceImage.PixelFormat);

如果源图像小于目标图像大小,这显然会失败,但你明白了。

【讨论】:

    【解决方案2】:

    如果需要,此方法将保存在中心裁剪的图像:

    bool SaveCroppedImage(Image image, int targetWidth, int targetHeight, string filePath)
    {
        ImageCodecInfo jpgInfo = ImageCodecInfo.GetImageEncoders().Where(codecInfo => codecInfo.MimeType == "image/jpeg").First();
        Image finalImage = image;
        System.Drawing.Bitmap bitmap = null;
        try
        {
            int left = 0;
            int top = 0;
            int srcWidth = targetWidth;
            int srcHeight = targetHeight;
            bitmap = new System.Drawing.Bitmap(targetWidth, targetHeight);
            double croppedHeightToWidth = (double)targetHeight / targetWidth;
            double croppedWidthToHeight = (double)targetWidth / targetHeight;
    
            if (image.Width > image.Height)
            {
                srcWidth = (int)(Math.Round(image.Height * croppedWidthToHeight));
                if (srcWidth < image.Width)
                {
                    srcHeight = image.Height;
                    left = (image.Width - srcWidth) / 2;
                }
                else
                {
                    srcHeight = (int)Math.Round(image.Height * ((double)image.Width / srcWidth));
                    srcWidth = image.Width;
                    top = (image.Height - srcHeight) / 2;
                }
            }
            else
            {
                srcHeight = (int)(Math.Round(image.Width * croppedHeightToWidth));
                if (srcHeight < image.Height)
                {
                    srcWidth = image.Width;
                    top = (image.Height - srcHeight) / 2;
                }
                else
                {
                    srcWidth = (int)Math.Round(image.Width * ((double)image.Height / srcHeight));
                    srcHeight = image.Height;
                    left = (image.Width - srcWidth) / 2;
                }
            }
            using (Graphics g = Graphics.FromImage(bitmap))
            {
                g.SmoothingMode = SmoothingMode.HighQuality;
                g.PixelOffsetMode = PixelOffsetMode.HighQuality;
                g.CompositingQuality = CompositingQuality.HighQuality;
                g.InterpolationMode = InterpolationMode.HighQualityBicubic;
                g.DrawImage(image, new Rectangle(0, 0, bitmap.Width, bitmap.Height), new Rectangle(left, top, srcWidth, srcHeight), GraphicsUnit.Pixel);
            }
            finalImage = bitmap;
        }
        catch { }
        try
        {
            using (EncoderParameters encParams = new EncoderParameters(1))
            {
                encParams.Param[0] = new EncoderParameter(Encoder.Quality, (long)100);
                //quality should be in the range [0..100] .. 100 for max, 0 for min (0 best compression)
                finalImage.Save(filePath, jpgInfo, encParams);
                return true;
            }
        }
        catch { }
        if (bitmap != null)
        {
            bitmap.Dispose();
        }
        return false;
    }
    

    【讨论】:

      【解决方案3】:

      使用目标大小创建新的位图对象。

      围绕该位图创建图形对象。

      在该 Graphcs 对象上,使用适当的参数调用 DrawImage(),这将从第一张图片中切出适当的片段。

      代码将类似于:

      Bitmap dstBitmap=new Bitmap(200, 200);
      using (Graphics g=Graphics.FromImage(dstBitmap)) 
      {
          srcBitmap.DrawImage(dstBitmap, /* cropping parameters here */);
      }
      //  at the end you'll have your bitmap in dstBitmap, ...
      

      我没有包含方法的文字参数,使用智能感知和手动来计算它们。

      【讨论】:

      • 这里的裁剪参数是什么意思?
      • 尝试自己找出参数。 DrawImage() 方法有几个重载,你必须找到一个适合你的。您必须定义一个 Rect,其中包含要剪切的图像部分的坐标。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-05-26
      • 2019-05-13
      • 1970-01-01
      • 2014-08-08
      • 2018-04-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多