Как создается тон сепии? - PullRequest
10 голосов
/ 30 июня 2009

Какие основные операции необходимы для создания тона сепии? Моим ориентиром является библиотека perl imagemagick, поэтому я легко могу использовать любую основную операцию. Я пытался квантовать (делая его в оттенках серого), раскрашивать, а затем улучшать изображение, но оно все еще немного размыто.

Ответы [ 4 ]

23 голосов
/ 26 февраля 2012

Пример кода конвертера сепии в C # доступен в моем ответе здесь: Что не так с этим алгоритмом преобразования тона сепии?

Алгоритм взят из этой страницы , каждый цвет входного пикселя преобразуется следующим образом:

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

Если любое из этих выходных значений больше 255, вы просто устанавливаете его до 255. Эти конкретные значения являются значениями для оттенка сепии, которые рекомендовано Microsoft.

4 голосов
/ 26 февраля 2012

Это в C #, однако основные понятия одинаковы. Скорее всего, вы сможете конвертировать это в 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);

}
1 голос
/ 18 января 2010

Посмотрите, как это реализовано в библиотеке AForge.NET, код C # здесь .

Основы кажутся

  • преобразовать его в цветовое пространство YIQ
  • изменить его
  • преобразовать обратно в RGB

Полный алгоритм находится в исходном коде, а также объяснены преобразования RGB -> YIQ и YIQ -> RGB.

1 голос
/ 30 июня 2009

Это просто, если вы используете командную строку imagemagic.

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

Использовать аргумент "-sepia-tone threshold" при конвертации.

Как ни странно, PerlMagick API, похоже, не включает в себя метод для этого напрямую:

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

... и без ссылки на какой-либо метод сепии.

...