2009-07-16 20 views
5

Estoy tratando de averiguar cómo usar FJCore para codificar un WriteableBitmap en un jpeg. Entiendo que WriteableBitmap proporciona los píxeles brutos, pero no estoy seguro de cómo convertirlo al formato que FJCore espera para su método JpegEncoder. JpegEncoder tiene dos sobrecargas, una toma una FluxJpeg.Core.Image y la otra toma una DecodedJpeg.Usando FJCore para codificar Silverlight WriteableBitmap

Estaba intentando crear un FluxJpeg.Core.Image pero se espera un byte [] [,] para los datos de la imagen. byte [n] [x, y] donde x es ancho e y es altura pero no sé lo que debería ser n.

Pensé que n debería ser 4, ya que eso correspondería a la información argb codificada en cada píxel, pero cuando probé FJCore arroja un argumento fuera de rango de excepción. Esto es lo que intenté. Raster es mi matriz byte [4] [x, y].

raster[0][x, y] = (byte)((pixel >> 24) & 0xFF); 
raster[1][x, y] = (byte)((pixel >> 16) & 0xFF); 
raster[2][x, y] = (byte)((pixel >> 8) & 0xFF); 
raster[3][x, y] = (byte)(pixel & 0xFF); 

Respuesta

13

¡Lo descubrí! Descargué FJCore from code.google.com y pasé por la clase de imagen. Solo espera los bytes RGB. Aquí está la función que escribí. Necesito la versión base64 de la imagen, así es como devuelve mi función.

private static string GetBase64Jpg(WriteableBitmap bitmap) 
    { 
     int width = bitmap.PixelWidth; 
     int height = bitmap.PixelHeight; 
     int bands = 3; 
     byte[][,] raster = new byte[bands][,]; 

     for (int i = 0; i < bands; i++) 
     { 
      raster[i] = new byte[width, height];  
     } 

     for (int row = 0; row < height; row++) 
     { 
      for (int column = 0; column < width; column++) 
      { 
       int pixel = bitmap.Pixels[width * row + column]; 
       raster[0][column, row] = (byte)(pixel >> 16); 
       raster[1][column, row] = (byte)(pixel >> 8); 
       raster[2][column, row] = (byte)pixel; 
      } 
     } 

     ColorModel model = new ColorModel { colorspace = ColorSpace.RGB }; 
     FluxJpeg.Core.Image img = new FluxJpeg.Core.Image(model, raster); 
     MemoryStream stream = new MemoryStream(); 
     JpegEncoder encoder = new JpegEncoder(img, 90, stream); 
     encoder.Encode(); 

     stream.Seek(0, SeekOrigin.Begin); 
     byte[] binaryData = new Byte[stream.Length]; 
     long bytesRead = stream.Read(binaryData, 0, (int)stream.Length); 

     string base64String = 
       System.Convert.ToBase64String(binaryData, 
               0, 
               binaryData.Length); 

     return base64String; 
    } 
+0

espero que no le importa, pero he utilizado el código de muestra y extiéndelo en un artículo completo, mira: http://blog.blueboxes.co.uk/2009/07/21/rendering-xaml-to-a-jpeg-using-silverlight-3/ y te atribuyó correctamente como bajo la licencia CC – John

+0

No hay problema. Me alegra que alguien se esté beneficiando de esto. – RHLopez

0

Suena como [n] debe ser la matriz de bytes de la imagen, he estado mirando en la codificación WriteableBitmap en un JPEG y encontré la misma biblioteca, pero no he estudiado en detalle, pero asumirían que se ser el caso, agregará más adelante a esta respuesta para ver si esto funciona, ya que aún no tengo la oportunidad de probarlo. Habrá algún método para obtener los bytes de un WritableBitmap en Silverlight, supongo, ya que es posible guardarlo en otros tipos.

2

Este código está bien y debería funcionar. Estoy usando mismo código para enviar secuencia de imágenes a través del servidor de servicios web y de regenerar la imagen utilizando estos bytes ... puede guardar estos bytes a Db también

[WebMethod] 
public string SaveImage(string data, string fileName) 
{ 
    byte[] imageBytes = System.Convert.FromBase64String(data); 

    MemoryStream mem = new MemoryStream(); 
    mem.Write(imageBytes, 0, imageBytes.Length); 

    System.Drawing.Image img = System.Drawing.Image.FromStream(mem); 
    img.Save("D:\\FinalTest.jpg");  
    return "Saved !"; 
} 
Cuestiones relacionadas