0

Anyone know how to add subtle noise to grayscale image? I have a grayscale image that I want to add some subtle black and white noise to. Anyone know how to do this?

I'm currently using this method, but this is just generating random colors and swapping existing pixels with those colors. How can I add some subtle black and white noise to only SOME pixels on a bitmap?

public static Bitmap applyFleaEffect(Bitmap source) {
// get source image size
 int width = source.getWidth();
  int height = source.getHeight();
 int[] pixels = new int[width * height];
 // get pixel array from source
 source.getPixels(pixels, 0, width, 0, 0, width, height);
 // create a random object
 Random random = new Random();

int index = 0;
// iteration through pixels
for(int y = 0; y < height; ++y) {
for(int x = 0; x < width; ++x) {
// get current index in 2D-matrix
index = y * width + x;
// get random color
int randColor = Color.rgb(random.nextInt(255),
  random.nextInt(255), random.nextInt(255));
// OR
pixels[index] |= randColor;

} } // output bitmap Bitmap bmOut = Bitmap.createBitmap(width, height, source.getConfig()); bmOut.setPixels(pixels, 0, width, 0, 0, width, height); return bmOut; } }

UPDATE: Adding complete code to show grayscale step, and attempted noise step

      //First, apply greyscale to make Image black and white
    Bitmap bmpGrayscale = Bitmap.createBitmap(width, height, mBitmap.getConfig());
    Canvas c = new Canvas(bmpGrayscale);
    Paint paint = new Paint();
    ColorMatrix cm = new ColorMatrix();
    cm.setSaturation(0);
    ColorMatrixColorFilter f = new ColorMatrixColorFilter(cm);
    paint.setColorFilter(f);

    //Apply noise after grayscale
    int[] pixels = new int[width * height];

    bmpGrayscale.getPixels(pixels, 0, width, 0, 0, width, height);
    // a random object
    Random random = new Random();

    int index = 0;

    // Note: Declare the c and randColor variables outside of the for loops
    int co = 0;
    int randColor = 0;
    // iteration through pixels
    for (int y = 0; y < height; ++y) {
        for (int x = 0; x < width; ++x) {
            if (random.nextInt(101) < percentNoise) {
                // Skip this iteration a certain percentage of the time
                continue;
            }
            // get current index in 2D-matrix
            index = y * width + x;


            co = random.nextInt(255);


            randColor = Color.rgb(co, co, co);
            pixels[index] |= randColor;




        }
    }
    // output bitmap
    mBitmap = Bitmap.createBitmap(width, height, bmpGrayscale.getConfig());
    mBitmap.setPixels(pixels, 0, width, 0, 0, width, height);

    c.drawBitmap(mBitmap, 0, 0, paint);
    return bmpGrayscale;
}
Jade Byfield
  • 4,668
  • 5
  • 30
  • 41
  • possible duplicate of [android noise effect on bitmap](http://stackoverflow.com/questions/16690730/android-noise-effect-on-bitmap) – Phantômaxx Oct 28 '14 at 20:01
  • @Funkystein How is this a possible duplicate when I'm asking a different question altogether? Also, the method from that question is the same I'm using. I just want to add subtler, black and white noise..not random colors – Jade Byfield Oct 28 '14 at 20:07
  • just use black instead of random colors. or (even better) apply the noise BEFORE converting to grayscale: the noise will be grayscaled too. – Phantômaxx Oct 29 '14 at 07:57
  • @Funkystein Makes sense, thanks. My thing is getting the noise to be subtle and light, not strong and all over the image. Do you think making the noise semi-transparent would help? – Jade Byfield Oct 29 '14 at 16:00
  • Well semitransparent will be "more subtle", harder to catch, but still sparse over the whole image (as dense as many iterations you run). I'm not aware of an algorithm to localize the "dust" near the contours (maybe you want this?) – Phantômaxx Oct 29 '14 at 16:09

1 Answers1

1

First, randColor is not likely to be a gray-scale color with your code. To generate a random, gray-scale color:

int c = random.nextInt(255);
int randColor = Color.rgb(c, c, c);

With that in mind, here is how I would re-write your code (note: adjust the percentNoise parameter to your liking):

public static Bitmap applyFleaEffect(Bitmap source, int percentNoise) {
    // get source image size
    int width = source.getWidth();
    int height = source.getHeight();
    int[] pixels = new int[width * height];
    // get pixel array from source
    source.getPixels(pixels, 0, width, 0, 0, width, height);
    // create a random object
    Random random = new Random();

    int index = 0;
    // Note: Declare the c and randColor variables outside of the for loops
    int c = 0;
    int randColor = 0;
    // iterate through pixels
    for (int y = 0; y < height; ++y) {
        for (int x = 0; x < width; ++x) {
            if (random.nextInt(101) < percentNoise) {
                // Skip this iteration a certain percentage of the time
                continue;
            }
            // get current index in 2D-matrix
            index = y * width + x;
            // get random color
            c = random.nextInt(255);
            randColor = Color.rgb(c, c, c);
            pixels[index] |= randColor;
        }
    }
    Bitmap bmOut = Bitmap.createBitmap(width, height, source.getConfig());
    bmOut.setPixels(pixels, 0, width, 0, 0, width, height);
    return bmOut;
}
B W
  • 692
  • 1
  • 8
  • 21
  • Thanks man. Could you take a look at my edit? I'm trying to first, convert the image to grayscale, and then add very minor noise to it. I played around with the percentNoise field. The closer to zero, it seems the bitmap has more white, and the close to 100 percentNoise is, the more black it has. Any insight on this? – Jade Byfield Oct 28 '14 at 20:49