2012-08-20 2 views
4

Я хотел бы сделать снимок в истинно черно-белом исполнении в моем приложении. Я искал решения (на этом сайте тоже), но я всегда нашел решение поместить фотографию в сером масштабе (например, в this topic), но это не то, что я ищу ...Сделайте монохромное изображение (черно-белое) с Android

Я также нашел тему предлагает следующее:

public static Bitmap createContrast(Bitmap src, double value) { 
// image size 

       int width = src.getWidth(); 
       int height = src.getHeight(); 
       // create output bitmap 
       Bitmap bmOut = Bitmap.createBitmap(width, height, src.getConfig()); 
       // color information 
       int A, R, G, B; 
       int pixel; 
       // get contrast value 
       double contrast = Math.pow((100 + value)/100, 2); 

     // scan through all pixels 
     for (int x = 0; x < width; ++x) { 
      for (int y = 0; y < height; ++y) { 
       // get pixel color 
       pixel = src.getPixel(x, y); 
       A = Color.alpha(pixel); 
       // apply filter contrast for every channel R, G, B 
       R = Color.red(pixel); 
       R = (int) (((((R/255.0) - 0.5) * contrast) + 0.5) * 255.0); 
       if (R < 0) { 
        R = 0; 
       } else if (R > 255) { 
        R = 255; 
       } 

       G = Color.red(pixel); 
       G = (int) (((((G/255.0) - 0.5) * contrast) + 0.5) * 255.0); 
       if (G < 0) { 
        G = 0; 
       } else if (G > 255) { 
        G = 255; 
       } 

       B = Color.red(pixel); 
       B = (int) (((((B/255.0) - 0.5) * contrast) + 0.5) * 255.0); 
       if (B < 0) { 
        B = 0; 
       } else if (B > 255) { 
        B = 255; 
       } 

       // set new pixel color to output bitmap 
       bmOut.setPixel(x, y, Color.argb(A, R, G, B)); 
      } 
     } 

     return bmOut; 

    } 

Но качество изображения ужасно ...

ли кто-нибудь, имеющий идею пожалуйста?

Thank you

+0

Ум ... это может быть глупый вопрос, но в чем разница между «истинным черно-белым» и оттенками серого? Оба сделаны в разных оттенках серого, но есть ли определенное определение терминов? Btw, «50 оттенков» шуток запрещены! :) – Alex

+0

@Alex - Мне было интересно то же самое и наткнулся на этот пример http://farm3.staticflickr.com/2393/3533241378_04c2b649c2_b.jpg. Верхнее изображение монохромное, а нижнее - оттенки серого. Я полагаю, что это зависит от того, что пытается сделать OP - захватить истинное монохроматическое изображение с камеры телефона в своем приложении или преобразовать существующие изображения? Единственная причина, о которой я прошу, состоит в том, что он уже опубликовал примеры их преобразования после факта :-) – shri046

+0

@ shri046 без каких-либо слов, ваш пример не является объяснением. Монохромный означает один цвет на фоне другого цвета. Черный и белый означает, что он черный на белом фоне. Я бы предположил, что приведенные вами примеры просто преобразуются из цвета в черно-белый с использованием разных фильтров. – slim

ответ

14

Если вы любите изображение для 1bit черный/белый вы можете использовать простой (& медленный) пороговый алгоритм

public static Bitmap createBlackAndWhite(Bitmap src) { 
    int width = src.getWidth(); 
    int height = src.getHeight(); 
    // create output bitmap 
    Bitmap bmOut = Bitmap.createBitmap(width, height, src.getConfig()); 
    // color information 
    int A, R, G, B; 
    int pixel; 

    // scan through all pixels 
    for (int x = 0; x < width; ++x) { 
     for (int y = 0; y < height; ++y) { 
      // get pixel color 
      pixel = src.getPixel(x, y); 
      A = Color.alpha(pixel); 
      R = Color.red(pixel); 
      G = Color.green(pixel); 
      B = Color.blue(pixel); 
      int gray = (int) (0.2989 * R + 0.5870 * G + 0.1140 * B); 

      // use 128 as threshold, above -> white, below -> black 
      if (gray > 128) 
       gray = 255; 
      else 
       gray = 0; 
      // set new pixel color to output bitmap 
      bmOut.setPixel(x, y, Color.argb(A, gray, gray, gray)); 
     } 
    } 
    return bmOut; 
} 

Но в зависимости от того, что не будет выглядеть хорошо, для достижения лучших результатов вам нужен дизеринг алгоритм, см. Algorithm overview - этот метод является пороговым.


Для 256 уровней серого преобразования:

согласно http://www.mathworks.de/help/toolbox/images/ref/rgb2gray.html рассчитать значение серого каждого пикселя, как gray = 0.2989 * R + 0.5870 * G + 0.1140 * B, который будет переводить на

public static Bitmap createGrayscale(Bitmap src) { 
    int width = src.getWidth(); 
    int height = src.getHeight(); 
    // create output bitmap 
    Bitmap bmOut = Bitmap.createBitmap(width, height, src.getConfig()); 
    // color information 
    int A, R, G, B; 
    int pixel; 

    // scan through all pixels 
    for (int x = 0; x < width; ++x) { 
     for (int y = 0; y < height; ++y) { 
      // get pixel color 
      pixel = src.getPixel(x, y); 
      A = Color.alpha(pixel); 
      R = Color.red(pixel); 
      G = Color.green(pixel); 
      B = Color.blue(pixel); 
      int gray = (int) (0.2989 * R + 0.5870 * G + 0.1140 * B); 
      // set new pixel color to output bitmap 
      bmOut.setPixel(x, y, Color.argb(A, gray, gray, gray)); 
     } 
    } 
    return bmOut; 
} 

Но это довольно медленно, так как у вас есть сделать это для миллионов пикселей отдельно.

https://stackoverflow.com/a/9377943/995891 имеет намного лучший способ достичь того же.

// code from that answer put into method from above 
public static Bitmap createGrayscale(Bitmap src) { 
    int width = src.getWidth(); 
    int height = src.getHeight(); 
    Bitmap bmOut = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); 
    Canvas canvas = new Canvas(bmOut); 
    ColorMatrix ma = new ColorMatrix(); 
    ma.setSaturation(0); 
    Paint paint = new Paint(); 
    paint.setColorFilter(new ColorMatrixColorFilter(ma)); 
    canvas.drawBitmap(src, 0, 0, paint); 
    return bmOut; 
} 
+0

Большое вам спасибо, ваш метод «createBlackAndWhite()» - это то, что я искал. Вы говорите немного медленно, но это правда черно-белое. Я попытаюсь немного его оптимизировать, но он отлично работает – Vince

+0

Один вопрос: в этом фрагменте кода «(0.2989 * R + 0.5870 * G + 0.1140 * B)», почему вы используете значения thoses: 0.2989, 0.5870 & 0,1140? – Vince

+1

@Vince Это один из возможных способов преобразования цвета в оттенки серого. Люди воспринимают яркость цветов по-разному (например, синий цвет ярче зеленого), поэтому он пытается соответствовать восприятию человека. Посмотрите на [изображения здесь] (http://en.wikipedia.org/wiki/HSL_and_HSV#Disadvantages) или прочитайте http://stackoverflow.com/questions/687261/converting-rgb-to-grayscale-intensity. – zapl

1

G = Color.red (pixel);

G = Цвет. зеленый (пиксель);

B = Color.red (pixel);

B = Цвет. синий (пиксель);

Посмотрите, поможет ли это (выделено полужирным шрифтом).

Смежные вопросы