[WPF] 이미지를 Base64 문자열로 바꿔주는 변환기 만들기

[WPF] 이미지를 Base64 문자열로 바꿔주는 변환기 만들기

Base64는 이진 데이터를 64개의 출력 가능한 ASCII 문자로 인코딩 하는 방식입니다. 여기서 64는 64진법이란 뜻입니다. Base64를 사용하게 되면 길이가 약 33퍼정도 더 늘어나는데 그럼에도 불구하고 사용하는 이유는 바이너리 데이터를 안전하게 전송하기 위해, 시스템과 상관없이 데이터를 전송하기 위해, 네트워크 요청 횟수를 줄이기 위해 사용합니다. 보통 작은 이미지를 Base64 문자열로 변환하는데 간단하게 IValueConverter를 사용하여 변환기를 만들어 보겠습니다.

코드

우선 MainWindow.xaml에 좌측에는 TextBox, 우측에서는 Image 컨트롤을 만들어줍니다.

<Window x:Class="WpfBase64.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfBase64"
        xmlns:cvt="clr-namespace:WpfBase64.Converter"
        mc:Ignorable="d"
        Title="MainWindow"
        Height="450"
        Width="800">
    <Window.DataContext>
        <local:MainViewModel/>
    </Window.DataContext>
    <Window.Resources>
        <cvt:Base64StringToBitmapImageConverter x:Key="Base64StringToBitmapImageConverter"/>
    </Window.Resources>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="300"/>
            <ColumnDefinition Width="5"/>
            <ColumnDefinition Width="1*"/>
        </Grid.ColumnDefinitions>

        <TextBox Grid.Column="0"
                 Text="{Binding BitmapImage, Converter={StaticResource Base64StringToBitmapImageConverter}, UpdateSourceTrigger=PropertyChanged}"
                 TextWrapping="Wrap"
                 VerticalScrollBarVisibility="Auto"
                 SpellCheck.IsEnabled="False"
                 VerticalAlignment="Stretch"
                 HorizontalAlignment="Stretch"/>

        <GridSplitter Grid.Column="1"
                      Margin="1"
                      Background="DarkGray"
                      HorizontalAlignment="Stretch"
                      VerticalAlignment="Stretch"/>

        <Image Grid.Column="2"
               Source="{Binding BitmapImage}"
               HorizontalAlignment="Stretch"
               VerticalAlignment="Stretch"/>
    </Grid>
</Window>

그 다음 MainViewModel.cs도 만들어 줍니다.

public class MainViewModel : BindableBase
{
    private BitmapImage bitmapImage = null;
    public BitmapImage BitmapImage { get => bitmapImage; set => SetProperty(ref bitmapImage, value); }

    public MainViewModel()
    {
        try
        {
            BitmapImage = new BitmapImage(new Uri($"pack://application:,,,/WpfBase64;component/Image/sample.jpg"));
        }
        catch (Exception e)
        {
            Debug.WriteLine($"{e}");
        }
    }
}

프로젝트 폴더에 Image 폴더를 만들어 sample.jpg를 넣어줍니다.

그리고 이 이미지를 우클릭 한 뒤 속성에 들어가서 빌드 작업리소스로 바꿔줍니다.

그 다음 프로젝트 폴더에 Converter 폴더를 만들어 이미지와 Base64 문자를 변환해주는 BitmapImageToBase64StringConverter.cs를 만들어줍니다.

코드는 아래와 같습니다.

public class Base64StringToBitmapImageConverter : IValueConverter
{
    public object? Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is BitmapImage bi)
        {
            PngBitmapEncoder encoder = new PngBitmapEncoder();
            encoder.Frames.Add(BitmapFrame.Create(bi));

            using (var ms = new MemoryStream())
            {
                encoder.Save(ms);
                byte[] imageBytes = ms.ToArray();

                string base64string = System.Convert.ToBase64String(imageBytes);
                return base64string;
            }
        }

        return Binding.DoNothing;
    }

    public object? ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value is string s)
        {
            if (string.IsNullOrEmpty(s))
                return null;

            try
            {
                BitmapImage bi = new BitmapImage();

                bi.BeginInit();
                bi.StreamSource = new MemoryStream(System.Convert.FromBase64String(s));
                bi.EndInit();

                return bi;
            }
            catch
            {
                return null;
            }
        }
        else
        {
            return null;
        }
    }
}

실행

실행하면 아래와 같이 sample.jpg 이미지를 불어오고 좌측에는 Base64 문자열이 표시됩니다.

실행 했을 땐 변환기에서 BitmapImage를 String으로 바꿔줬는데 만약 좌측 TextBox의 문자열을 잘라내서 다시 붙여 넣으면 String을 BitmapImage로 바꿔주는 작업을 하게 됩니다.

이상으로 Base64에 대해 알아보았습니다.


github : https://github.com/3001ssw/c_sharp/tree/main/WPF/WPF_Basic/WpfBase64