简体   繁体   English

在 C# 中,如何将 Base64 字符串转换为图像,然后旋转它?

[英]In C#, how can I convert a Base64 string into an Image, then rotate it?

I have images saved in Base64 that are a mixture of landscape and portrait.我在 Base64 中保存了横向和纵向混合的图像。 I want to display them all as landscape.我想将它们全部显示为风景。

I'm able to convert the Base64 strings into BitmapImages, then set that as an Image.Source, but I can't get the rotation to work.我能够将 Base64 字符串转换为 BitmapImages,然后将其设置为 Image.Source,但我无法使旋转工作。

In this class, I get the base64 from XML, then call SetupImage which sets up the source of a System.Windows.Controls.Image object.在这个类中,我从 XML 获取 base64,然后调用 SetupImage,它设置 System.Windows.Controls.Image 对象的源。

I've tried 2 ways of rotating the image (when the width is less than the height) both are in this code.我已经尝试了两种旋转图像的方法(当宽度小于高度时)都在这段代码中。 When I use the Rotation on the BitmapImage there is no affect on the displayed image.当我在 BitmapImage 上使用 Rotation 时,对显示的图像没有影响。 When I use the RotateTransform on the Image the images don't display at all.当我在图像上使用 RotateTransform 时,图像根本不显示。

public class TrayImage
{
    [XmlAttribute("id")]
    public string ID { get; set; }
    [XmlAttribute("data")]
    public string Data { get; set; }

    /// <summary>
    /// Create an Image from the Base64 Data
    /// </summary>
    internal void SetupImage(ref System.Windows.Controls.Image image)
    {
        if (this.Data != null)
        {
            // Convert the Base64 to a BitmapImage
            byte[] _BinaryData = Convert.FromBase64String(this.Data);

            BitmapImage _ImageBitmap = new BitmapImage();
            _ImageBitmap.BeginInit();
            _ImageBitmap.StreamSource = new MemoryStream(_BinaryData);
            _ImageBitmap.EndInit();

            // If the image is portrait, rotate it
            if (_ImageBitmap.Width < _ImageBitmap.Height)
            {
                // only use one rotation method at a time!!
                //_ImageBitmap.Rotation = Rotation.Rotate90;
            }

            image.Source = _ImageBitmap;

            // If the image is portrait, rotate it
            if( image.Source.Width < image.Source.Height)
            {
                // only use one rotation method at a time!!
                RotateTransform _RotateTransform = new RotateTransform(90);
                image.RenderTransform = _RotateTransform;
            }
        }
    }
}

Should I be using something else to convert, then rotate the images?我应该使用其他东西来转换,然后旋转图像吗?

Like this: This is for illustration only code is not tested!像这样:这只是为了说明代码未测试!

public static class ImageHelpers
{
    punlic byte[] ConvertFromBase64(btye[] data)
    {
        return Convert.FromBase64String(data)
    }

    public  Image Rotate90FromData(byte[] data)
    {
        Image image = null;
        if (data != null)
        {             
            BitmapImage _ImageBitmap = new BitmapImage();
            _ImageBitmap.BeginInit();
            _ImageBitmap.StreamSource = new MemoryStream(data);
            _ImageBitmap.EndInit();

            image.Source = _ImageBitmap;

            // If the image is portrait, rotate it
            if( image.Source.Width < image.Source.Height)
            {
                RotateTransform _RotateTransform = new RotateTransform(90);
                image.RenderTransform = _RotateTransform;
            }
        }
        return Image;
    }
}

public class Main
{
    public void Start()
    {
        var data64 = ImageHelpers.ConvertFromBase64(somevar);
        Image rotatedImage = ImageHelpers.Rotate90FromData(data64);

    }
}

After combing suggestions here, and on other questions I came up with a working solution.在梳理了这里的建议以及其他问题后,我想出了一个可行的解决方案。

These are my "usings"这些是我的“用途”

using System;
using System.Xml.Serialization;
using System.IO;
using System.Windows.Media.Imaging;
using System.Drawing;

Here's my full class这是我的全班

public class TrayImage
{
    [XmlAttribute("id")]
    public string ID { get; set; }
    [XmlAttribute("data")]
    public string Data { get; set; }

    /// <summary>
    /// Create an Image from the Base64 Data
    /// </summary>
    internal System.Windows.Controls.Image SetupImage()
    {
        System.Windows.Controls.Image _Image = new System.Windows.Controls.Image();

        if (this.Data != null)
        {
            BitmapImage _BitmapImage = this.CreateBitmapImage();
            Bitmap _Bitmap = this.BitmapImage2Bitmap(_BitmapImage);

            // If the image is portrait, rotate it
            if (_Bitmap.Width < _Bitmap.Height)
            {
                _Bitmap = this.RotateImage(_Bitmap, 90);
            }

            _Image.Source = this.BitmapToBitmapImage(_Bitmap);
        }

        return _Image;
    }

    /// <summary>
    /// Convert a Bitmap into a BitmapImage
    /// </summary>
    private BitmapImage BitmapToBitmapImage(Bitmap bitmap)
    {
        using (MemoryStream _MemoryStream = new MemoryStream())
        {
            bitmap.Save(_MemoryStream, System.Drawing.Imaging.ImageFormat.Bmp);
            _MemoryStream.Position = 0;
            BitmapImage _BitmapImage = new BitmapImage();
            _BitmapImage.BeginInit();
            _BitmapImage.StreamSource = _MemoryStream;
            _BitmapImage.CacheOption = BitmapCacheOption.OnLoad;
            _BitmapImage.EndInit();

            return _BitmapImage;
        }
    }

    /// <summary>
    /// Convert a Base64 String into a BitmapImage
    /// </summary>
    private BitmapImage CreateBitmapImage()
    {
        byte[] _BinaryData = Convert.FromBase64String(this.Data);

        BitmapImage _ImageBitmap = new BitmapImage();
        _ImageBitmap.BeginInit();
        _ImageBitmap.StreamSource = new MemoryStream(_BinaryData);
        _ImageBitmap.EndInit();

        return _ImageBitmap;
    }

    /// <summary>
    /// Convert a BitmapImage into a Bitmap
    /// </summary>
    private Bitmap BitmapImage2Bitmap(BitmapImage bitmapImage)
    {
        using (MemoryStream _OutStream = new MemoryStream())
        {
            BitmapEncoder _Encoder = new BmpBitmapEncoder();
            _Encoder.Frames.Add(BitmapFrame.Create(bitmapImage));
            _Encoder.Save(_OutStream);
            System.Drawing.Bitmap _Bitmap = new System.Drawing.Bitmap(_OutStream);

            return new Bitmap(_Bitmap);
        }
    }

    /// <summary>
    /// Rotate a Bitmap
    /// </summary
    private Bitmap RotateImage(Bitmap bitmap, float angle)
    {
        int _Width = bitmap.Width;
        int _Height = bitmap.Height;
        float _MoveX = (float)_Height / 2;

        // Create bitmap with Height / Width revered
        Bitmap _ReturnBitmap = new Bitmap(_Height, _Width);

        // Make a graphics object from the empty bitmap
        using (Graphics _Graphics = Graphics.FromImage(_ReturnBitmap))
        {
            // Move image along x axis
            _Graphics.TranslateTransform(_MoveX, 0);

            // Rotate image
            _Graphics.RotateTransform(angle);

            // Move image back along x axis
            // NB, now it's been rotated, the x and y axis have swapped from our perspective.
            _Graphics.TranslateTransform(0, -_MoveX);

            // Draw passed in image onto graphics object
            _Graphics.DrawImage(bitmap, new Point(0, 0));
        }
        return _ReturnBitmap;
    }
}

I did it like this:我是这样做的:

using System.IO;    
using System.Drawing;

public Bitmap RotateBase64Image(string base64Image)
{
     Bitmap result = null;
     try
     {
          if (!string.IsNullOrEmpty(base64Image))
          {
              //Check if base64 string has a header
              if (base64Image.IndexOf("base64") >= 0 && base64Image.IndexOf(",") > 0)
              {
                  //get image data and exclude header
                  base64Image = base64Image.Split(',')[1];
              }
              using (MemoryStream ms = new MemoryStream(Convert.FromBase64String(base64Image)))
              {
                  using (Bitmap bitmap = new Bitmap(ms))
                  {
                      //rotate 90 degree clockwise with no flip
                      bitmap.RotateFlip(RotateFlipType.Rotate90FlipNone);
                      //rotate 180 degree clockwise with no flip
                      bitmap.RotateFlip(RotateFlipType.Rotate180FlipNone);
                      //rotate 270 degree clockwise with no flip
                      bitmap.RotateFlip(RotateFlipType.Rotate270FlipNone);
                      //Flip Image horizontally with out any rotation
                      bitmap.RotateFlip(RotateFlipType.RotateNoneFlipX);
                      //Flip Image vertically with out any rotation
                      bitmap.RotateFlip(RotateFlipType.RotateNoneFlipY);

                      result = (Bitmap)bitmap.Clone();                            
                }
            }
        }
    }
    catch { }

    return result;
}

And also if you need result as base64 again:而且,如果您再次需要结果为 base64:

public string ConvertBitmapToBase64(Bitmap image)
{
    string result = "";
    try
    {
        using (MemoryStream ms2 = new MemoryStream())
        {
            image.Save(ms2, System.Drawing.Imaging.ImageFormat.Png);
            return Convert.ToBase64String(ms2.ToArray());

            //If you need the result with header
            //return "data:image/png;base64," + Convert.ToBase64String(ms2.ToArray());
        }
    }
    catch { }

    return result;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM