代码中的像素化图像

时间:2013-03-21 12:09:32

标签: android image pixel

我已经搜索了如何通过代码在android中对图像进行像素化,结果是多种多样的。

我找到了关于如何应用此处的其他效果的库和教程:http://xjaphx.wordpress.com/learning/tutorials/

有人可以为我清理一下,在android中动态像素化像素的最简单方法是什么

如果它是一个函数,我可以使用多少轮或者我想要图像像素化,这将是方便的。

提前感谢。

5 个答案:

答案 0 :(得分:4)

像素化图像的最简单方法是使用“最近邻居”算法缩小图像,然后使用相同的算法进行放大。

对图像进行过滤以尝试查找平均值需要花费更多时间,但实际上并没有对结果质量进行任何改进,毕竟你故意想要使图像失真。

答案 1 :(得分:2)

我之前已经在vb.net中完成了这项工作,并且很容易将其制作成一个函数,其参数可以控制你想要它的像素化程度。

基本思想是在X宽度和y高度的块的部分中扫描图像。对于每个块,您可以找到平均RGB值并将所有这些像素设置为该颜色。块大小越小,像素化越少。

int avR,avB,avG; // store average of rgb 
    int pixel;
    Bitmap bmOut = Bitmap.createBitmap(width, height, src.getConfig());

    for(int x = 0; x < width; x+= pixelationAmount) { // do the whole image
        for(int y = 0; y < height; y++ pixelationamount) {
            avR = 0; avG = 0; avB =0;

            for(int xx =x; xx <pixelationAmount;xx++){// YOU WILL WANT TO PUYT SOME OUT OF                                      BOUNDS CHECKING HERE
                for(int yy= y; yy <pixelationAmount;yy++){ // this is scanning the colors
                    pixel = src.getPixel(x, y);
                    avR += (int) (color.red(pixel);
                    avG+= (int) (color.green(pixel);
                    avB += (int) (color.blue(pixel);
                }
            }
            avrR/= pixelationAmount^2; //divide all by the amount of samples taken to get an average
            avrG/= pixelationAmount^2;
            avrB/= pixelationAmount^2;

            for(int xx =x; xx <pixelationAmount;xx++){// YOU WILL WANT TO PUYT SOME OUT OF BOUNDS CHECKING HERE
                for(int yy= y; yy <pixelationAmount;yy++){ // this is going back over the block 
                    bmOut.setPixel(xx, yy, Color.argb(255, avR, avG,avB)); //sets the block to the average color
                }
            }

        }

    }

抱歉格式不好(快速写在记事本中),但认为它可能会给你一个框架来制作你自己的像素化功能

答案 2 :(得分:1)

以上算法的更正有效:

    Bitmap bmOut = Bitmap.createBitmap(OriginalBitmap.getWidth(),OriginalBitmap.getHeight(),OriginalBitmap.getConfig());
    int pixelationAmount = 50; //you can change it!!
    int width = OriginalBitmap.getWidth();
    int height = OriginalBitmap.getHeight();
    int avR,avB,avG; // store average of rgb 
    int pixel;

    for(int x = 0; x < width; x+= pixelationAmount) { // do the whole image
        for(int y = 0; y < height; y+= pixelationAmount) {
            avR = 0; avG = 0; avB =0;


            int bx = x + pixelationAmount;
            int by = y + pixelationAmount;
            if(by >= height) by = height;
            if(bx >= width)bx = width;
            for(int xx =x; xx < bx;xx++){// YOU WILL WANT TO PUYT SOME OUT OF                                      BOUNDS CHECKING HERE
                for(int yy= y; yy < by;yy++){ // this is scanning the colors

                    pixel = OriginalBitmap.getPixel(xx, yy);
                    avR += (int) (Color.red(pixel));
                    avG+= (int) (Color.green(pixel));
                    avB += (int) (Color.blue(pixel));
                }
            }
            avR/= pixelationAmount^2; //divide all by the amount of samples taken to get an average
            avG/= pixelationAmount^2;
            avB/= pixelationAmount^2;

            for(int xx =x; xx < bx;xx++)// YOU WILL WANT TO PUYT SOME OUT OF BOUNDS CHECKING HERE
                for(int yy= y; yy <by;yy++){ // this is going back over the block 
                    bmOut.setPixel(xx, yy, Color.argb(255, avR, avG,avB)); //sets the block to the average color
                }


        }

    }
    iv.setImageBitmap(bmOut);

无论如何,这不是我想要的

答案 3 :(得分:0)

我完全改变了以前的算法,它确实做了类似马赛克过滤器的事情! 我们的想法是用下面的块像素替换每个块像素 简单地使用这个功能:

public void filter(){
    Bitmap bmOut = Bitmap.createBitmap(OriginalBitmap.getWidth(),OriginalBitmap.getHeight(),OriginalBitmap.getConfig());

    int pixelationAmount = 10;
    Bitmap a = Bitmap.createBitmap(pixelationAmount,pixelationAmount,OriginalBitmap.getConfig());
    Bitmap b = Bitmap.createBitmap(pixelationAmount,pixelationAmount,OriginalBitmap.getConfig());
    int width = OriginalBitmap.getWidth();
    int height = OriginalBitmap.getHeight();
    int pixel;
    int counter = 1;
    int px = 0;int py = 0;int pbx=0;int pby=0;
    for(int x = 0; x < width; x+= pixelationAmount) { // do the whole image
        for(int y = 0; y < height; y+= pixelationAmount) {
            int bx = x + pixelationAmount;
            int by = y + pixelationAmount;
            if(by >= height) by = height;
            if(bx >= width)bx = width;
            int xxx = -1;
            int yyy = -1;
            for(int xx =x; xx < bx;xx++){// YOU WILL WANT TO PUYT SOME OUT OF                                      BOUNDS CHECKING HERE
                xxx++;
                yyy = -1;
                for(int yy= y; yy < by;yy++){ // this is scanning the colors
                    yyy++;
                    pixel = OriginalBitmap.getPixel(xx, yy);
                    if(counter == 1)
                    {
                        a.setPixel(xxx, yyy, pixel);
                        px = x;//previous x
                        py = y;//previous y
                        pbx = bx;
                        pby = by;
                    }
                    else
                        b.setPixel(xxx, yyy, pixel);
                }
            }
            counter++;
            if(counter == 3)
            {
                int xxxx = -1;
                int yyyy = -1;
                for(int xx =x; xx < bx;xx++)
                {
                    xxxx++;
                    yyyy = -1;
                    for(int yy= y; yy <by;yy++){ 
                        yyyy++;
                        bmOut.setPixel(xx, yy, b.getPixel(xxxx, yyyy)); 
                    }
                }
                for(int xx =px; xx < pbx;xx++)
                {
                    for(int yy= py; yy <pby;yy++){  
                        bmOut.setPixel(xx, yy, a.getPixel(xxxx, yyyy)); //sets the block to the average color
                    }
                }

                counter = 1;
            }


        }

    }
    image_view.setImageBitmap(bmOut);
}

答案 4 :(得分:0)

这是我使用的代码:

ImageFilter是父类:

public abstract class ImageFilter {

protected int [] pixels;
protected int width;
protected int height;

public ImageFilter (int [] _pixels, int _width,int _height){
    setPixels(_pixels,_width,_height);
}


public void setPixels(int [] _pixels, int _width,int _height){
    pixels = _pixels;
    width = _width;
    height = _height;
}

/**
 * a weighted Euclidean distance in RGB space
 * @param c1
 * @param c2
 * @return
 */
public double colorDistance(int c1, int c2)
{
    int red1 = Color.red(c1);
    int red2 = Color.red(c2);
    int rmean = (red1 + red2) >> 1;
    int r = red1 - red2;
    int g = Color.green(c1) - Color.green(c2);
    int b = Color.blue(c1) - Color.blue(c2);
    return Math.sqrt((((512+rmean)*r*r)>>8) + 4*g*g + (((767-rmean)*b*b)>>8));
}

public abstract int[]  procImage();

}

public class PixelateFilter extends ImageFilter {

int pixelSize;
int[] colors;

/**
 * @param _pixels
 * @param _width
 * @param _height
 */
public PixelateFilter(int[] _pixels, int _width, int _height) {
    this(_pixels, _width, _height, 10);
}

public PixelateFilter(int[] _pixels, int _width, int _height, int _pixelSize) {
    this(_pixels, _width, _height, _pixelSize, null);
}

public PixelateFilter(int[] _pixels, int _width, int _height, int _pixelSize, int[] _colors) {
    super(_pixels, _width, _height);
    pixelSize = _pixelSize;
    colors = _colors;
}

/* (non-Javadoc)
 * @see imageProcessing.ImageFilter#procImage()
 */
@Override
public int[] procImage() {
    for (int i = 0; i < width; i += pixelSize) {
        for (int j = 0; j < height; j += pixelSize) {
            int rectColor = getRectColor(i, j);
            fillRectColor(rectColor, i, j);
        }
    }
    return pixels;
}

private int getRectColor(int col, int row) {
    int r = 0, g = 0, b = 0;
    int sum = 0;
    for (int x = col; x < col + pixelSize; x++) {
        for (int y = row; y < row + pixelSize; y++) {
            int index = x + y * width;
            if (index < width * height) {
                int color = pixels[x + y * width];
                r += Color.red(color);
                g += Color.green(color);
                b += Color.blue(color);
            }

        }
    }
    sum = pixelSize * pixelSize;
    int newColor = Color.rgb(r / sum, g / sum, b / sum);
    if (colors != null)
        newColor = getBestMatch(newColor);
    return newColor;
}

private int getBestMatch(int color) {
    double diff = Double.MAX_VALUE;
    int res = color;
    for (int c : colors) {
        double currDiff = colorDistance(color, c);
        if (currDiff < diff) {
            diff = currDiff;
            res = c;
        }
    }
    return res;
}


private void fillRectColor(int color, int col, int row) {
    for (int x = col; x < col + pixelSize; x++) {
        for (int y = row; y < row + pixelSize; y++) {
            int index = x + y * width;
            if (x < width && y < height && index < width * height) {
                pixels[x + y * width] = color;
            }

        }
    }
}



public static final Bitmap changeToPixelate(Bitmap bitmap, int pixelSize, int [] colors) {
    int width = bitmap.getWidth();
    int height = bitmap.getHeight();

    int[] pixels = new int[width * height];
    bitmap.getPixels(pixels, 0, width, 0, 0, width, height);

    PixelateFilter pixelateFilter = new PixelateFilter(pixels, width, height, pixelSize, colors);

    int[] returnPixels = pixelateFilter.procImage();
    Bitmap returnBitmap = Bitmap.createBitmap(returnPixels, width, height, Bitmap.Config.ARGB_8888);

    return returnBitmap;

}

}

以下是您使用它的方式:

    int [] colors = new int [] { Color.BLACK,Color.WHITE,Color.BLUE,Color.CYAN,Color.RED};
    final Bitmap bmOut  = PixelateFilter.changeToPixelate(OriginalBitmap, pixelSize,colors);