2009-06-29 35 views
7

¿Cuáles son las operaciones básicas necesarias para crear un tono sepia? Mi punto de referencia es la biblioteca perl imagemagick, por lo que puedo usar fácilmente cualquier operación básica. Intenté cuantificar (haciéndolo en escala de grises), colorear y luego mejorar la imagen, pero todavía está un poco borrosa.¿Cómo se crea un tono sepia?

Respuesta

1

Es fácil si utiliza la línea de comandos de imagemagic.

http://www.imagemagick.org/script/convert.php

Usar el "umbral -sepia de tono" argumento al convertir.

Curiosamente, no parece que la API PerlMagick para incluir un método para hacer esto directamente:

http://www.imagemagick.org/script/perl-magick.php

... y no hace referencia a cualquier método de la sepia.

+0

Ya que tengo un objeto ImageMagick en Perl este no es el camino más directo pero podría funcionar ... pero no parecen tener la opción de utilizar otros colores para el efecto – user83358

1

Eche un vistazo a cómo se implementa en la biblioteca AForge.NET, el código C# es here.

Los fundamentos parecen ser

  • transformarla en el espacio de color YIQ
  • modificarlo
  • transformará de nuevo a RGB

El alrogithm completo se encuentra en el código fuente, además de se explican las transformaciones RGB -> YIQ y YIQ -> RGB.

+0

El enlace de código no funciona más ... = ( –

+0

alguien puede actualizar el enlace? – codejammer

+1

@codejammer http://bit.ly/ZP0Y3x –

20

Código de ejemplo de un convertidor de sepia en C# está disponible en mi respuesta aquí: What is wrong with this sepia tone conversion algorithm?

El algoritmo proviene de this page, cada color de píxeles de entrada se transforma de la siguiente manera:

outputRed = (inputRed * .393) + (inputGreen *.769) + (inputBlue * .189) 
outputGreen = (inputRed * .349) + (inputGreen *.686) + (inputBlue * .168) 
outputBlue = (inputRed * .272) + (inputGreen *.534) + (inputBlue * .131) 

Si alguno de estos valores de salida es mayor que 255, simplemente configúrelo en 255. Estos valores específicos son los valores para tono sepia que son recomendados por Microsoft.

+0

Necesitarás usar Math.Min probablemente. Intenté hacer el cheque para 255 después de esas tres líneas y se producirá un error. Estaba enfrentando el mismo problema el día de hoy cuando estaba tratando de hacer un tono sepia para mi programa. – BigBug

+0

Pero, ¿y si quiero algo diferente para cha nge el filtro, ¿cómo puedo llegar a estos valores? al igual que mi pregunta es cómo llegamos a conocer estos valores, ¿necesitamos simplemente poner valores diferentes una y otra vez? – AHF

3

Esto está en C#, sin embargo, los conceptos básicos son los mismos. Es probable que puedas convertir esto en perl.

private void SepiaBitmap(Bitmap bmp) 
{ 
    Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height); 
    System.Drawing.Imaging.BitmapData bmpData = bmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, 
     System.Drawing.Imaging.PixelFormat.Format32bppRgb); 

    IntPtr ptr = bmpData.Scan0; 

    int numPixels = bmpData.Width * bmp.Height; 
    int numBytes = numPixels * 4; 
    byte[] rgbValues = new byte[numBytes]; 

    System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, numBytes); 
    for (int i = 0; i < rgbValues.Length; i += 4) 
    { 
     rgbValues[i + 2] = (byte)Math.Min((.393 * red) + (.769 * green) + (.189 * (blue)), 255.0); //red 
     rgbValues[i + 1] = (byte)Math.Min((.349 * red) + (.686 * green) + (.168 * (blue)), 255.0); //green 
     rgbValues[i + 0] = (byte)Math.Min((.272 * red) + (.534 * green) + (.131 * (blue)), 255.0); //blue 
     if ((rgbValues[i + 2]) > 255) 
     { 
      rgbValues[i + 2] = 255; 
     } 

     if ((rgbValues[i + 1]) > 255) 
     { 
      rgbValues[i + 1] = 255; 
     } 
     if ((rgbValues[i + 0]) > 255) 
     { 
      rgbValues[i + 0] = 255; 
     } 
    } 

    System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, numBytes); 
    this.Invalidate(); 
    bmp.UnlockBits(bmpData); 

} 
+0

cuál es el punto de usar matemáticas.min y usando if para verificar si es más grande de 255? – AndreaBogazzi

+0

El 'Math.Min' es necesario para fijar los valores calculados al rango de bytes. Esas declaraciones 'si' que siguen son completamente inútiles. 'rgbValues' es una matriz' byte', por lo que ninguno de sus valores puede ser> 255 – saucecontrol

Cuestiones relacionadas