【问题标题】:C# WPF Picture ratio vertical and/or horizontalC# WPF 图片比例垂直和/或水平
【发布时间】:2017-12-20 01:36:22
【问题描述】:

大家好,我发现这张图片调整大小代码here,我正在尝试将其调整为我当前的代码。

private void resizeImage(string path, string originalFilename, 
                     /* note changed names */
                     int canvasWidth, int canvasHeight, 
                     /* new */
                     int originalWidth, int originalHeight)
{
    Image image = Image.FromFile(path + originalFilename);

    System.Drawing.Image thumbnail = 
        new Bitmap(canvasWidth, canvasHeight); // changed parm names
    System.Drawing.Graphics graphic = 
                 System.Drawing.Graphics.FromImage(thumbnail);

    graphic.InterpolationMode = InterpolationMode.HighQualityBicubic;
    graphic.SmoothingMode = SmoothingMode.HighQuality;
    graphic.PixelOffsetMode = PixelOffsetMode.HighQuality;
    graphic.CompositingQuality = CompositingQuality.HighQuality;

    /* ------------------ new code --------------- */

    // Figure out the ratio
    double ratioX = (double) canvasWidth / (double) originalWidth;
    double ratioY = (double) canvasHeight / (double) originalHeight;
    // use whichever multiplier is smaller
    double ratio = ratioX < ratioY ? ratioX : ratioY;

    // now we can get the new height and width
    int newHeight = Convert.ToInt32(originalHeight * ratio);
    int newWidth = Convert.ToInt32(originalWidth * ratio);

    // Now calculate the X,Y position of the upper-left corner 
    // (one of these will always be zero)
    int posX = Convert.ToInt32((canvasWidth - (originalWidth * ratio)) / 2);
    int posY = Convert.ToInt32((canvasHeight - (originalHeight * ratio)) / 2);

    graphic.Clear(Color.White); // white padding
    graphic.DrawImage(image, posX, posY, newWidth, newHeight);

    /* ------------- end new code ---------------- */

    System.Drawing.Imaging.ImageCodecInfo[] info =
                     ImageCodecInfo.GetImageEncoders();
    EncoderParameters encoderParameters;
    encoderParameters = new EncoderParameters(1);
    encoderParameters.Param[0] = new EncoderParameter(Encoder.Quality,
                     100L);            
    thumbnail.Save(path + newWidth + "." + originalFilename, info[1], 
                     encoderParameters);
}

还有我当前的代码:

public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
    string path = value as string;

    if (path != null) {
       //create new stream and create bitmap frame
       var bitmapImage = new BitmapImage();

       bitmapImage.BeginInit();
       bitmapImage.StreamSource = new FileStream(path, FileMode.Open, FileAccess.Read);
       //load the image now so we can immediately dispose of the stream
       bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
       bitmapImage.EndInit();

       //clean up the stream to avoid file access exceptions when attempting to delete images
       bitmapImage.StreamSource.Dispose();

       return bitmapImage;
    } else {
       return DependencyProperty.UnsetValue;
    }
}

问题是 resizeImage 代码使用 Image 而我当前的代码使用 BitmapImage

我一直在尝试找到将其中一种格式转换为一种格式或另一种格式的方法,但我似乎没有成功。

不确定 resizeImage 是否是我需要的,因为我无法按原样运行它,但我要做的就是检测图像是水平的还是垂直的。如果它是垂直的,则调整它的大小(更大或更小),使其适合我的指定区域。同样,水平方向与垂直方向相同。

【问题讨论】:

  • 因此,如果位图的纵横比是 portrait(即它比宽度高),您想以某种方式将其转换为 landscape,但是不要旋转它。那应该怎么做?通过切割零件,或通过扭曲它(例如,仅在一个方向上缩放)? BitmapImage 肯定由 Image 元素显示,该元素已经能够均匀或不均匀地拉伸其 Source,因此可能根本不需要操作 BitmapImage。
  • 我怀疑你可以把所有这些代码都扔掉并使用图片的Stretch属性。

标签: c# wpf bitmapimage


【解决方案1】:

有很多方法可以转换大小,但我想直接回答您的问题,因为网络上没有太多关于将 BitmapSource System.Drawing 转换为.位图。 (有很多文章都说走另一条路)。

此函数会将任何 WPF BitmapSource(包括 BitmapImage,它是一个 BitmapSource)转换为 System.Drawing.Bitmap:

private System.Drawing.Bitmap ConvertBitmapSourceToDrawingBitmap(BitmapSource image)
{
    int width = Convert.ToInt32(image.Width);
    int height = Convert.ToInt32(image.Height);
    int stride = Convert.ToInt32(width * ((image.Format.BitsPerPixel + 7) / 8) + 0.5);

    byte[] bits = new byte[height * stride];
    image.CopyPixels(bits, stride, 0);

    System.Drawing.Bitmap bitmap = null;
    unsafe
    {
        fixed (byte* pBits = bits)
        {
            IntPtr ptr = new IntPtr(pBits);
            bitmap = new System.Drawing.Bitmap(width, height, stride, System.Drawing.Imaging.PixelFormat.Format32bppPArgb, ptr);
        }
    }

    return bitmap;
}

为了测试它,我使用了这段代码:

    System.Windows.Media.Imaging.BitmapSource bitmapSource;
    using (System.IO.Stream stm = System.IO.File.Open("c:\\foo_in.png", System.IO.FileMode.Open, System.IO.FileAccess.Read))
    {
        // Since we're not specifying a System.Windows.Media.Imaging.BitmapCacheOption, the pixel format
        // will be System.Windows.Media.PixelFormats.Pbgra32.
        bitmapSource = System.Windows.Media.Imaging.BitmapFrame.Create(
            stm,
            System.Windows.Media.Imaging.BitmapCreateOptions.None,
            System.Windows.Media.Imaging.BitmapCacheOption.OnLoad);
    }
    System.Drawing.Bitmap bmp = ConvertBitmapSourceToDrawingBitmap(bitmapSource);
    bmp.Save("c:\\foo_out.png", System.Drawing.Imaging.ImageFormat.Png);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-19
    • 2020-04-30
    • 2011-10-29
    • 2017-03-27
    相关资源
    最近更新 更多