2009-06-29 10 views
7

Quali sono le operazioni di base necessarie per creare un tono seppia? Il mio punto di riferimento è la libreria perl imagemagick, quindi posso facilmente utilizzare qualsiasi operazione di base. Ho provato a quantizzare (renderlo in scala di grigi), a colorare e quindi a migliorare l'immagine, ma è ancora un po 'sfocato.Come viene creato un tono seppia?

risposta

1

È facile se si utilizza la riga di comando imagemagic.

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

Utilizzare la "soglia -sepia-tone" argomento durante la conversione.

Stranamente, l'API PerlMagick non sembra includere un metodo per fare questo direttamente:

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

... e nessun riferimento a qualsiasi metodo di seppia.

+0

Dal momento che ho un oggetto imagemagick in Perl questo non è il modo più diretto, ma potrebbe funzionare ... ma non sembra avere la possibilità di utilizzare altri colori per l'effetto – user83358

1

Date un'occhiata a come è implementato nella libreria AForge.NET, il codice C# è here.

Le basi sembrano essere

  • trasformarlo nello spazio colore YIQ
  • modificarlo
  • trasformare di nuovo a RGB

L'alrogithm completo è nel codice sorgente, oltre a le trasformazioni RGB -> YIQ e YIQ -> RGB sono spiegate.

+0

Il collegamento di codice non funziona più ... = ( –

+0

qualcuno può aggiornare il collegamento? – codejammer

+1

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

20

codice di esempio di un convertitore di seppia in C# è disponibile nella mia risposta qui: What is wrong with this sepia tone conversion algorithm?

L'algoritmo viene da this page, ogni colore dei pixel di ingresso si trasforma nel seguente modo:

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

Se uno qualsiasi di questi valori di uscita è maggiore di 255, è sufficiente impostarlo da a 255. Questi valori specifici sono i valori per tonalità seppia che sono consigliati da Microsoft.

+0

Avrai bisogno di usare Math.Min Probabilmente ho provato a fare il controllo per 255 dopo quelle tre righe e si verificherà un errore.Avevo affrontato lo stesso problema in precedenza oggi quando stavo cercando di fare un tono seppia per il mio programma .. – BigBug

+0

Ma cosa succede se voglio qualcosa di diverso da cha nge il filtro allora come posso arrivare a questi valori? come la mia domanda è come siamo venuti a conoscenza di questi valori, dobbiamo semplicemente inserire diversi valori ancora e ancora? – AHF

3

Questo è in C#, tuttavia, i concetti di base sono gli stessi. Probabilmente sarai in grado di convertire questo in 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

qual è il punto di utilizzo della matematica.min e usando il se per verificare se è più grande di 255? – AndreaBogazzi

+0

Il 'Math.Min' è necessario per bloccare i valori calcolati sull'intervallo di byte. Queste affermazioni 'if' che seguono sono completamente inutili. 'rgbValues' è una matrice' byte', quindi nessuno dei suoi valori può essere> 255 – saucecontrol

Problemi correlati