2013-03-21 47 views
1

我已經搜索瞭如何在Android中通過代碼像素化圖像,結果是多種多樣的。像素代碼中的圖像

我發現庫和教程如何申請等功效這裏找到:http://xjaphx.wordpress.com/learning/tutorials/

有人可以明確的事情對我來說,什麼是Android

對飛像素化圖像的最簡單方法

如果它是一個函數,我可以做多少輪或者我想要多少圖像像素,它也會很方便。

提前致謝。

+0

見http://stackoverflow.com/questions/4047031/help-with-the-theory-behind-a-pixelate-algorithm – Michael 2013-03-21 12:12:03

回答

3

像素化圖像的最簡單方法是使用「最近鄰居」算法縮放圖像,然後使用相同的算法進行放大。

過濾圖片試圖找到一個平均需要更多的時間,但實際上並沒有給結果質量有任何改善,畢竟你有意讓你的圖像扭曲。

+0

有一個代碼Google使用此方法提供的示例:https://android.googlesource.com/platform/development/+/master/samples/devbytes/graphics/ImagePixelization/src/com/example/android/imagepixelization/ImagePixelization.java – 2017-05-12 12:21:37

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 
       } 
      } 

     } 

    } 

約壞格式對不起(用記事本寫的很快),但認爲它可能給你一個框架,以使自己的像素化功能

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); 

反正這是不是我一直在尋找

+0

平均值計算錯誤。avR = avR/n,其中n在avR + =(int)(Color.red(pixel))時遞增;發生。如果你解決這個問題,你會得到一個正確的像素化圖像,而不僅僅是隨機顏色塊。 – lxknvlk 2016-07-02 15:39:27

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); 
} 
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);