2010-04-30 13 views

Respuesta

20

fin he encontrado una solución a mi problema:

  1. transformar la imagen a escala de grises, utilizando así una conocida colormatriz.
  2. Usar Método SetThreshold de ImageAttributes clase para establecer el umbral que separa el negro de blanco.

Este es el código C#:

using (Graphics gr = Graphics.FromImage(SourceImage)) // SourceImage is a Bitmap object 
     {     
      var gray_matrix = new float[][] { 
       new float[] { 0.299f, 0.299f, 0.299f, 0, 0 }, 
       new float[] { 0.587f, 0.587f, 0.587f, 0, 0 }, 
       new float[] { 0.114f, 0.114f, 0.114f, 0, 0 }, 
       new float[] { 0,  0,  0,  1, 0 }, 
       new float[] { 0,  0,  0,  0, 1 } 
      }; 

      var ia = new System.Drawing.Imaging.ImageAttributes(); 
      ia.SetColorMatrix(new System.Drawing.Imaging.ColorMatrix(gray_matrix)); 
      ia.SetThreshold(0.8); // Change this threshold as needed 
      var rc = new Rectangle(0, 0, SourceImage.Width, SourceImage.Height); 
      gr.DrawImage(SourceImage, rc, 0, 0, SourceImage.Width, SourceImage.Height, GraphicsUnit.Pixel, ia);     
     } 

He Benchmarked este código y es aproximadamente 40 veces más rápido que el píxel por píxel manipulación.

+4

Esto hará en blanco y negro (no en escala de grises): 'Nuevo ColorMatrix (New Single()() _ {New Single() {1.5, 1.5, 1.5, 0, 0}, _ New Single() {1.5, 1.5, 1.5 , 0, 0}, _ Nuevo single() {1.5, 1.5, 1.5, 0, 0}, _ Nuevo single() {0, 0, 0, 1, 0}, _ New Single() {-1, - 1, -1, 0, 1}}) ' –

+1

@Otaku: No, su código no funcionará. Le dará un borde más nítido, pero aún valores grises. – Pedery

+0

@Pedery: no debe implementarlo correctamente, eso es exactamente cómo hacer en blanco y negro (sin matices de gris). –

2

Si desea que parezca medio decente, es probable que desee aplicar algún tipo de oscilación.

Aquí hay una discusión completa, aunque un poco anticuado:

http://www.efg2.com/Lab/Library/ImageProcessing/DHALF.TXT

+0

quiero blanco y negro, porque esto sería parte de un proceso de reconocimiento de imágenes, es decir, la detección de algunas formas, independientemente de sus colores. – vbocan

+0

En ese caso, probablemente pueda salirse con la suya en la línea de "Pixel [x, y] = ((R (x, y) + G (x, y) + B (x, y))/3) > = 127? 1: 0 ". –

+1

Esto es lo que ya he intentado, pero alterando la imagen píxel por píxel muy lentamente. – vbocan

3

versión VB.NET:

Using gr As Graphics = Graphics.FromImage(SourceImage) 'SourceImage is a Bitmap object' 
    Dim gray_matrix As Single()() = { 
    New Single() {0.299F, 0.299F, 0.299F, 0, 0}, 
    New Single() {0.587F, 0.587F, 0.587F, 0, 0}, 
    New Single() {0.114F, 0.114F, 0.114F, 0, 0}, 
    New Single() {0, 0, 0, 1, 0}, 
    New Single() {0, 0, 0, 0, 1} 
    } 
    Dim ia As New System.Drawing.Imaging.ImageAttributes 
    ia.SetColorMatrix(New System.Drawing.Imaging.ColorMatrix(gray_matrix)) 
    ia.SetThreshold(0.8) 
    Dim rc As New Rectangle(0, 0, SourceImage.Width, SourceImage.Height) 
    gr.DrawImage(SourceImage, rc, 0, 0, SourceImage.Width, SourceImage.Height, GraphicsUnit.Pixel, ia) 
End Using 
0

Esa matriz de color BW corrompe el archivo, desde 300dpi fuente el resultado es 96 ppp con 200-300kb tamaño final. Puedo convertir Kofax para jugar, pero el TIF está corrupto para ser procesado en el servidor. También el tamaño no puede ser aceptado.

La mejor manera es simplemente cambiar la codificación a CCITT, que solo BW. El resultado sigue siendo correcto, se mantiene a 300 ppp y el tamaño del archivo resultante es de 30-50 kb. También mucho más eficiente y más rápido que System.DrawImage.

Ésta es la solución perfecta:

public void toCCITT(string tifURL) 
{ 
    byte[] imgBits = File.ReadAllBytes(tifURL); 

    using (MemoryStream ms = new MemoryStream(imgBits)) 
    { 
     using (Image i = Image.FromStream(ms)) 
     { 
      EncoderParameters parms = new EncoderParameters(1); 
      ImageCodecInfo codec = ImageCodecInfo.GetImageDecoders() 
               .FirstOrDefault(decoder => decoder.FormatID == ImageFormat.Tiff.Guid); 

      parms.Param[0] = new EncoderParameter(Encoder.Compression, (long)EncoderValue.CompressionCCITT4); 

      i.Save(@"c:\test\result.tif", codec, parms); 
     } 
    } 
} 
Cuestiones relacionadas