一个简单的解决方案
在下文中,我仅根据正常的3维空间距离公式更改图像中的每个像素。我根据像素与每种颜色的距离来决定像素应为黑色还是白色。例如,(1,2,3)比(255,255,255)更接近(0,0,0),因此将其确定为黑色。我敢肯定还有更多聪明的算法。这只是一个简单的
MainActivity.java
package com.example.binarizeimage;import java.io.File;import java.io.FileNotFoundException;import java.io.IOException;import java.io.RandomAccessFile;import java.nio.MappedByteBuffer;import java.nio.channels.FileChannel;import java.nio.channels.FileChannel.MapMode;import android.app.Activity;import android.graphics.Bitmap;import android.graphics.Bitmap.Config;import android.graphics.BitmapFactory;import android.graphics.Color;import android.os.Bundle;import android.os.Environment;import android.widget.ImageView;import com.example.binarizeimage.R.drawable;public class MainActivity extends Activity { private static final boolean TRASNPARENT_IS_BLACK = false; private static final double SPACE_BREAKING_POINT = 13.0/30.0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //this is the original image Bitmap theOriginalImage = BitmapFactory.depreResource(this.getResources(), drawable.ic_launcher); //this is the image that is binarized Bitmap binarizedImage = convertToMutable(theOriginalImage); // I will look at each pixel and use the function shouldBeBlack to decide // whether to make it black or otherwise white for(int i=0;i<binarizedImage.getWidth();i++) { for(int c=0;c<binarizedImage.getHeight();c++) { int pixel = binarizedImage.getPixel(i, c); if(shouldBeBlack(pixel)) binarizedImage.setPixel(i, c, Color.BLACK); else binarizedImage.setPixel(i, c, Color.WHITE); } } ImageView iv = (ImageView) findViewById(R.id.imageView1); ImageView ivb = (ImageView) findViewById(R.id.ImageView01); //show the original image iv.setImageBitmap(BitmapFactory.depreResource(this.getResources(), drawable.ic_launcher)); //show the binarized image ivb.setImageBitmap(binarizedImage); } private static boolean shouldBeBlack(int pixel) { int alpha = Color.alpha(pixel); int redValue = Color.red(pixel); int bluevalue = Color.blue(pixel); int greenValue = Color.green(pixel); if(alpha == 0x00) //if this pixel is transparent let me use TRASNPARENT_IS_BLACK return TRASNPARENT_IS_BLACK; // distance from the white extreme double distanceFromWhite = Math.sqrt(Math.pow(0xff - redValue, 2) + Math.pow(0xff - bluevalue, 2) + Math.pow(0xff - greenValue, 2)); // distance from the black extreme //this should not be computed and might be as well a function of distanceFromWhite and the whole distance double distanceFromBlack = Math.sqrt(Math.pow(0x00 - redValue, 2) + Math.pow(0x00 - bluevalue, 2) + Math.pow(0x00 - greenValue, 2)); // distance between the extremes //this is a constant that should not be computed :p double distance = distanceFromBlack + distanceFromWhite; // distance between the extremes return ((distanceFromWhite/distance)>SPACE_BREAKING_POINT); } public static Bitmap convertToMutable(Bitmap imgIn) { try { //this is the file going to use temporally to save the bytes. // This file will not be a image, it will store the raw image data. File file = new File(Environment.getExternalStorageDirectory() + File.separator + "temp.tmp"); //Open an RandomAccessFile //Make sure you have added uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" //into AndroidManifest.xml file RandomAccessFile randomAccessFile = new RandomAccessFile(file, "rw"); // get the width and height of the source bitmap. int width = imgIn.getWidth(); int height = imgIn.getHeight(); Config type = imgIn.getConfig(); //Copy the byte to the file //Assume source bitmap loaded using options.inPreferredConfig = Config.ARGB_8888; FileChannel channel = randomAccessFile.getChannel(); MappedByteBuffer map = channel.map(MapMode.READ_WRITE, 0, imgIn.getRowBytes()*height); imgIn.copyPixelsToBuffer(map); //recycle the source bitmap, this will be no longer used. imgIn.recycle(); System.gc();// try to force the bytes from the imgIn to be released //Create a new bitmap to load the bitmap again. Probably the memory will be available. imgIn = Bitmap.createBitmap(width, height, type); map.position(0); //load it back from temporary imgIn.copyPixelsFromBuffer(map); //close the temporary file and channel , then delete that also channel.close(); randomAccessFile.close(); // delete the temp file file.delete(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return imgIn; }}activity_main.xml *



