2009-02-16 24 views
12

Estoy tratando de convertir de System.Windows.Controls.Image a byte[] y yo no sabía qué método de la clase de imagen podría ayudar en este escenario, por cierto yo realmente no sé lo que debo hacer, porque en mi LINQ modelo el campo aparece como Binary tipo, tengo que cambiar esto si quiero guardarlo como un tipo byte[]?WPF imagen para byte []

encontré código publicado aquí, pero sin utilizar WPF:

Bitmap newBMP = new Bitmap(originalBMP, newWidth, newHeight); 
System.IO.MemoryStream stream = new System.IO.MemoryStream(); 
newBMP.Save(stream, System.Drawing.Imaging.ImageFormat.Bmp); 
PHJProjectPhoto myPhoto = new PHJProjectPhoto { 
    ProjectPhoto = stream.ToArray(), // <<--- This will convert your stream to a byte[] 
    OrderDate = DateTime.Now, 
    ProjectPhotoCaption = ProjectPhotoCaptionTextBox.Text, 
    ProjectId = selectedProjectId 
}; 

Respuesta

29

Solución real ... si desea guardar imágenes jpg desde System.Windows.Control.Image cuando su campo mapeado de base de datos en su ORM es byte []/byte []/Bynary

public byte[] getJPGFromImageControl(BitmapImage imageC) 
{ 
     MemoryStream memStream = new MemoryStream();    
     JpegBitmapEncoder encoder = new JpegBitmapEncoder(); 
     encoder.Frames.Add(BitmapFrame.Create(imageC)); 
     encoder.Save(memStream); 
     return memStream.ToArray(); 
} 

llamada como:

getJPGFromImageControl(firmaUno.Source as BitmapImage) 

Hopes ayuda :)

+0

¿qué pasa con windows-8 ??? – Suny

+0

Bueno uno 1+ :-) – Sunny

+0

sí ... pero bastante lento, 470+ milisegundos ... :( – lauCosma

11

no sé cómo se declara su imagen, pero supongamos que tenemos esta declaración XAML:

<Image x:Name="img"> 
    <Image.Source> 
     <BitmapImage UriSource="test.png" /> 
    </Image.Source> 
</Image> 

A continuación, puede convertir el contenido de prueba.png a una matriz de bytes de esta manera:

var bmp = img.Source as BitmapImage; 

int height = bmp.PixelHeight; 
int width = bmp.PixelWidth; 
int stride = width * ((bmp.Format.BitsPerPixel + 7)/8); 

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

mi xaml es: Im configurar fuente en código subyacente, ¿cuál es mejor? –

+0

sorpresa es el ahorro: 0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 ... :/ –

+0

que está funcionando. Gracias gix –

1
public byte[] BufferFromImage(BitmapImage imageSource) 
{   
    Stream stream = imageSource.StreamSource; 
    byte[] buffer = null; 

    if (stream != null && stream.Length > 0) 
    { 
     using (BinaryReader br = new BinaryReader(stream)) 
     { 
      buffer = br.ReadBytes((Int32)stream.Length); 
     } 
    } 

    return buffer; 
} 

sería otra forma, pero la diferencia es que tiene menos bytes [x] que la primera solución

+2

Creo que depende de cómo se inicializa la imagen. Si configura un BitmapImage, StreamSource parece ser nulo. – gix

+1

Estoy configurando la imagen.Fuente como BitmapImage y recuperando un BitmapImage nulo, también intenté convertirlo a BitmapImage, ¿cuál es la solución para esto? Parece un molde inválido, pero veo esta solución en todas partes, incluido http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/dee0e287-b345-4e01-888a-ecfb9c3f40b0/. – TheWolf

1

Esto funciona para mí:

MemoryStream stream = (MemoryStream)bitmapImage.StreamSource; 
byte[] data = stream.ToArray(); 
1

También es posible usar copyPixels de BitmapSources método

int stride = snapshot.PixelWidth * (snapshot.Format.BitsPerPixel/8); 
byte[] data = new byte[stride * snapshot.PixelHeight]; 
snapshot.CopyPixels(data, stride, 0); 
var memoryStream = new MemoryStream(data); 
2
public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 
    } 

    private void btnBrowse_Click(object sender, RoutedEventArgs e) 
    { 
     var of = new OpenFileDialog(); 
     of.Filter = "Image files (*.png;*.jpeg)|*.png;*.jpeg|All files (*.*)|*.*"; 
     var res = of.ShowDialog(); 
     if (res.HasValue) 
     { 
      imgPreview.Source = new BitmapImage(new Uri(of.FileName)); 

      var t = Utils.ConvertBitmapSourceToByteArray(imgPreview.Source as BitmapSource); 
      var d = Utils.ConvertBitmapSourceToByteArray(new BitmapImage(new Uri(of.FileName))); 
      var s = Utils.ConvertBitmapSourceToByteArray(imgPreview.Source); 
      var enc = Utils.ConvertBitmapSourceToByteArray(new PngBitmapEncoder(), imgPreview.Source); 
      //imgPreview2.Source = Utils.ConvertByteArrayToBitmapImage(enc); 
      imgPreview2.Source = Utils.ConvertByteArrayToBitmapImage2(enc); 
      //var i = 0; 


     } 
     else 
     { 
      MessageBox.Show("Select a currect file..."); 

     } 
    } 

} 

/util.cs/

public class Utils 
{ 
    public static byte[] ConvertBitmapSourceToByteArray(BitmapEncoder encoder, ImageSource imageSource) 
    { 
     byte[] bytes = null; 
     var bitmapSource = imageSource as BitmapSource; 

     if (bitmapSource != null) 
     { 
      encoder.Frames.Add(BitmapFrame.Create(bitmapSource)); 

      using (var stream = new MemoryStream()) 
      { 
       encoder.Save(stream); 
       bytes = stream.ToArray(); 
      } 
     } 

     return bytes; 
    } 

    public static byte[] ConvertBitmapSourceToByteArray(BitmapSource image) 
    { 
     byte[] data; 
     BitmapEncoder encoder = new JpegBitmapEncoder(); 
     encoder.Frames.Add(BitmapFrame.Create(image)); 
     using (MemoryStream ms = new MemoryStream()) 
     { 
      encoder.Save(ms); 
      data = ms.ToArray(); 
     } 
     return data; 
    } 
    public static byte[] ConvertBitmapSourceToByteArray(ImageSource imageSource) 
    { 
     var image = imageSource as BitmapSource; 
     byte[] data; 
     BitmapEncoder encoder = new JpegBitmapEncoder(); 
     encoder.Frames.Add(BitmapFrame.Create(image)); 
     using (MemoryStream ms = new MemoryStream()) 
     { 
      encoder.Save(ms); 
      data = ms.ToArray(); 
     } 
     return data; 
    } 
    public static byte[] ConvertBitmapSourceToByteArray(Uri uri) 
    { 
     var image = new BitmapImage(uri); 
     byte[] data; 
     BitmapEncoder encoder = new JpegBitmapEncoder(); 
     encoder.Frames.Add(BitmapFrame.Create(image)); 
     using (MemoryStream ms = new MemoryStream()) 
     { 
      encoder.Save(ms); 
      data = ms.ToArray(); 
     } 
     return data; 
    } 
    public static byte[] ConvertBitmapSourceToByteArray(string filepath) 
    { 
     var image = new BitmapImage(new Uri(filepath)); 
     byte[] data; 
     BitmapEncoder encoder = new JpegBitmapEncoder(); 
     encoder.Frames.Add(BitmapFrame.Create(image)); 
     using (MemoryStream ms = new MemoryStream()) 
     { 
      encoder.Save(ms); 
      data = ms.ToArray(); 
     } 
     return data; 
    } 

    public static BitmapImage ConvertByteArrayToBitmapImage(Byte[] bytes) 
    { 
     var stream = new MemoryStream(bytes); 
     stream.Seek(0, SeekOrigin.Begin); 
     var image = new BitmapImage(); 
     image.BeginInit(); 
     image.StreamSource = stream; 
     image.EndInit(); 
     return image; 
    } 
} 
0

me gustan los codificadores y decodificadores de los nombres: System.Windows.Media.Imaging

public static class Extensions {   

    public static byte[] ToByteArray(this BitmapSource bitmapSource) { 

     var encoder = new JpegBitmapEncoder(); 
     encoder.Frames.Add(BitmapFrame.Create(bitmapSource)); 

     using (var stream = new MemoryStream()) { 
      encoder.Save(stream); 
      return stream.ToArray(); 
     } 
    } 

    public static BitmapSource ToBitmapSource(this byte[] bytes) { 

     using (var stream = new MemoryStream(bytes)) { 
      var decoder = new JpegBitmapDecoder(stream, BitmapCreateOptions.None, BitmapCacheOption.Default); 
      return decoder.Frames.First(); 
     } 
    } 
} 

Se puede utilizar la siguiente manera:

var bytes = bitmapSource.ToByteArray(); 

O así:

var bitmapSource = bytes.ToBitmapSource();