none
Работа с изображениями (WPF) RRS feed

  • Вопрос

  • Здравствуйте.
    Подскажите пожалуйста, как в WPF можно быстро преобразовть изображение в массив пикселей(или байт) и как из массива байт получить изображение.
    • Перемещено Tagore Bandlamudi 2 октября 2010 г. 22:10 MSDN Forums consolidation (От:Разработка Windows-приложений)
    25 ноября 2009 г. 17:48

Ответы

  • Нашел ответ самостоятельно. Если кому интересно, то сделал так:

    public class ImageLoader
    {
    /// <summary>
    /// Загрузка изображения в массив байт
    /// </summary>
    /// <param name="path">путь к файлу</param>
    /// <returns></returns>
    public static byte[,] LoadImage( string path )
    {
    Uri myUri = new Uri( path, UriKind.RelativeOrAbsolute );
    BmpBitmapDecoder decoder = new BmpBitmapDecoder( myUri, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default );
    BitmapSource bs = decoder.Frames[0];
    //Конвертируем изображение в оттенки серого
    FormatConvertedBitmap fcb = new FormatConvertedBitmap( bs, PixelFormats.Gray8, BitmapPalettes.BlackAndWhite, 1 );
    bs = fcb;
    byte[] arr = new byte[( int )( bs.Width * bs.Height )];
    //Извлекаем пиксели
    bs.CopyPixels( arr, ( int )( 8 * bs.Width ) / 8, 0 );
    int count = 0;
    byte[,] img = new byte[( int )bs.Height, ( int )bs.Width];
    //формируем двумерный массив
    for ( int i = 0; i < bs.Height; ++i )
    {
    for ( int j = 0; j < bs.Width; ++j )
    {
    img[i, j] = arr[count++];
    }
    }
    return img;
    }

    /// <summary>
    /// Преобразование массива байт в изображение
    /// </summary>
    /// <param name="img">массив байт</param>
    /// <returns></returns>
    public static BitmapSource BitmapFromByteArr( byte[,] img )
    {
    byte[] arr = new byte[( img.GetUpperBound( 1 ) + 1 ) * ( img.GetUpperBound( 0 ) + 1 )];
    int count = 0;
    for ( int i = 0; i <= img.GetUpperBound(0); ++i )
    {
    for ( int j = 0; j <= img.GetUpperBound(1); ++j )
    {
    arr[count++] = img[i, j];
    }
    }
    return BitmapSource.Create( img.GetUpperBound(1) ,img.GetUpperBound(0), 96, 96, PixelFormats.Gray8, BitmapPalettes.BlackAndWhite, arr, ( int )( 8 * (img.GetUpperBound(1)+1)) / 8 );
    }

    Изображение кодируется в оттенки серого, но кому нужно, тот может кодировать во что угодно, заменив строчку
    FormatConvertedBitmap fcb = new FormatConvertedBitmap( bs, PixelFormats.Gray8, BitmapPalettes.BlackAndWhite, 1 );
    и
    BitmapSource.Create( img.GetUpperBound(1) ,img.GetUpperBound(0), 96, 96, PixelFormats.Gray8, BitmapPalettes.BlackAndWhite, arr, ( int )( 8 * (img.GetUpperBound(1)+1)) / 8 );

     

     

     

    • Помечено в качестве ответа I.Vorontsov 26 ноября 2009 г. 14:16
    25 ноября 2009 г. 19:28

Все ответы

  • Нашел ответ самостоятельно. Если кому интересно, то сделал так:

    public class ImageLoader
    {
    /// <summary>
    /// Загрузка изображения в массив байт
    /// </summary>
    /// <param name="path">путь к файлу</param>
    /// <returns></returns>
    public static byte[,] LoadImage( string path )
    {
    Uri myUri = new Uri( path, UriKind.RelativeOrAbsolute );
    BmpBitmapDecoder decoder = new BmpBitmapDecoder( myUri, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default );
    BitmapSource bs = decoder.Frames[0];
    //Конвертируем изображение в оттенки серого
    FormatConvertedBitmap fcb = new FormatConvertedBitmap( bs, PixelFormats.Gray8, BitmapPalettes.BlackAndWhite, 1 );
    bs = fcb;
    byte[] arr = new byte[( int )( bs.Width * bs.Height )];
    //Извлекаем пиксели
    bs.CopyPixels( arr, ( int )( 8 * bs.Width ) / 8, 0 );
    int count = 0;
    byte[,] img = new byte[( int )bs.Height, ( int )bs.Width];
    //формируем двумерный массив
    for ( int i = 0; i < bs.Height; ++i )
    {
    for ( int j = 0; j < bs.Width; ++j )
    {
    img[i, j] = arr[count++];
    }
    }
    return img;
    }

    /// <summary>
    /// Преобразование массива байт в изображение
    /// </summary>
    /// <param name="img">массив байт</param>
    /// <returns></returns>
    public static BitmapSource BitmapFromByteArr( byte[,] img )
    {
    byte[] arr = new byte[( img.GetUpperBound( 1 ) + 1 ) * ( img.GetUpperBound( 0 ) + 1 )];
    int count = 0;
    for ( int i = 0; i <= img.GetUpperBound(0); ++i )
    {
    for ( int j = 0; j <= img.GetUpperBound(1); ++j )
    {
    arr[count++] = img[i, j];
    }
    }
    return BitmapSource.Create( img.GetUpperBound(1) ,img.GetUpperBound(0), 96, 96, PixelFormats.Gray8, BitmapPalettes.BlackAndWhite, arr, ( int )( 8 * (img.GetUpperBound(1)+1)) / 8 );
    }

    Изображение кодируется в оттенки серого, но кому нужно, тот может кодировать во что угодно, заменив строчку
    FormatConvertedBitmap fcb = new FormatConvertedBitmap( bs, PixelFormats.Gray8, BitmapPalettes.BlackAndWhite, 1 );
    и
    BitmapSource.Create( img.GetUpperBound(1) ,img.GetUpperBound(0), 96, 96, PixelFormats.Gray8, BitmapPalettes.BlackAndWhite, arr, ( int )( 8 * (img.GetUpperBound(1)+1)) / 8 );

     

     

     

    • Помечено в качестве ответа I.Vorontsov 26 ноября 2009 г. 14:16
    25 ноября 2009 г. 19:28
  • Я бы сделал по-другому - загрузил бы все это в System.Drawing.Bitmap, сделал бы LockBits(), вытащил Scan0+width+height+stride и передал бы их С++ обработчику, а там уже менял бы битмап. Конверсии в BitmapSource (если они нужны) сделал бы отдельно.

    В качестве примера можно посмотреть тут.

    - Dmitri Nesteruk
    30 ноября 2009 г. 13:12
  • Спс вам огромное.
    21 марта 2017 г. 7:00