Copy a bit matrix from bitmap image in ANDROID programming
Based on your given explanations I made the following a Sample project and the code is given below -
public class ActivityImage extends AppCompatActivity{
Button grab;
CustomImageView iv_custom;
ImageView iv_later;
Bitmap bitmapBG,bitmapOrg;
int iMin,jMin,iMax,jMax;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.so_particular_img_section);
iv_custom = (CustomImageView)findViewById(R.id.iv_custom);
iv_custom.setDrawingCacheEnabled(true);
iv_later = (ImageView)findViewById(R.id.iv_later);
grab = (Button)findViewById(R.id.btn_grab);
grab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
iv_custom.buildDrawingCache();
bitmapBG = iv_custom.getDrawingCache();
getSelectedRegionOnly();
}
});
}
/**
* this method will return the whole image But only the selected region is highlighted and the rest section is simply white
*/
private void getSelectedRegionWithBG(){
int[] mainImageArray = iv_custom.getImagePixels();
int[] bgImageArray = new int[bitmapBG.getWidth() * bitmapBG.getHeight()];
int[] finalImageArray = new int[bitmapBG.getWidth() * bitmapBG.getHeight()];
bitmapBG.getPixels(bgImageArray,0,bitmapBG.getWidth(), 0, 0, bitmapBG.getWidth(), bitmapBG.getHeight());
if(mainImageArray.length == bgImageArray.length){
for(int i = 0; i < (bitmapBG.getWidth() * bitmapBG.getHeight());i++){
if(mainImageArray[i] == bgImageArray[i]){
finalImageArray[i] = Color.WHITE;
}else{
finalImageArray[i] = mainImageArray[i];
}
}
Bitmap finalBitmap = Bitmap.createBitmap(bitmapBG.getWidth(), bitmapBG.getHeight(), Bitmap.Config.ARGB_8888);
// Set the pixels
finalBitmap.setPixels(finalImageArray, 0, finalBitmap.getWidth(), 0, 0, finalBitmap.getWidth(), finalBitmap.getHeight());
iv_later.setImageBitmap(finalBitmap);
}else{
Toast.makeText(ActivityImage.this,"Array length are not same",Toast.LENGTH_SHORT).show();
}
}
/**
* This method will select only the selected region from the main image and create the bitmap
*/
private void getSelectedRegionOnly(){
generateBounds();
int count = 0;
int[] finalImageArray = new int[(1+iMax - iMin) * (1+jMax - jMin)];
Bitmap finalBitmap = Bitmap.createBitmap((1+jMax - jMin), (1+iMax - iMin), Bitmap.Config.ARGB_8888);
for(int i = iMin; i <= iMax; i++){
for(int j = jMin; j <= jMax; j++){
if(bitmapBG.getPixel(j,i) != bitmapOrg.getPixel(j,i)) {
finalImageArray[count] = bitmapOrg.getPixel(j, i);
}else {
finalImageArray[count] = Color.WHITE;
}
count++;
}
}
// Set the pixels
finalBitmap.setPixels(finalImageArray, 0, finalBitmap.getWidth(), 0, 0, finalBitmap.getWidth(), finalBitmap.getHeight());
iv_later.setImageBitmap(finalBitmap);
}
/**
* generates the bound of the coloured region
*/
private void generateBounds(){
bitmapOrg = iv_custom.getMainBitmap();
iMax = jMax = 0;
iMin = jMin = bitmapBG.getWidth() * bitmapBG.getHeight();
for(int i = 0; i < bitmapBG.getHeight(); i++){
for(int j = 0; j < bitmapBG.getWidth(); j++){
if(bitmapBG.getPixel(j,i) != bitmapOrg.getPixel(j,i)){
if(iMin > i){
iMin = i;
}
if(jMin > j){
jMin = j;
}
if(iMax < i){
iMax = i;
}
if(jMax < j){
jMax = j;
}
}
}
}
}
}
The layout file -
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="GRAB IMAGE"
android:id="@+id/btn_grab"
android:layout_alignParentBottom="true"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff"
android:id="@+id/demo"
android:orientation="vertical"
android:layout_above="@id/btn_grab"
>
<com.wandertails.stackovrflw.CustomImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/iv_custom"
android:layout_weight="1" />
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/iv_later"
android:layout_weight="1"/>
</LinearLayout>
</RelativeLayout>
Finally the custom image View -
public class CustomImageView extends ImageView {
int width,height;
Bitmap sample;
Context con;
Paint paint=new Paint();
public CustomImageView(Context context) {
super(context);
con = context;
}
public CustomImageView(Context context, AttributeSet attrs) {
super(context, attrs);
con = context;
}
public CustomImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
con = context;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
sample = createBackground(width,height,con);
canvas.drawBitmap(sample,0,0,paint);
canvas.drawBitmap(createForeground(width,height,con),0,0,paint);
paint.setColor(Color.RED);
//canvas.drawRect(400,400,600,600,paint);
//canvas.drawCircle(400,400,200,paint);
}
public int[] getImagePixels(){
int[] pixels = new int[sample.getWidth() * sample.getHeight()];
sample.getPixels(pixels, 0, sample.getWidth(), 0, 0, sample.getWidth(), sample.getHeight());
return pixels;
}
public Bitmap getMainBitmap(){
return sample;
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
width = w;
height = h;
}
private Bitmap createBackground(int width, int height, Context con) {
Bitmap logo = null;
logo = BitmapFactory.decodeResource(con.getResources(), R.drawable.sample);
return Bitmap.createScaledBitmap(logo,width,height,true).copy(Bitmap.Config.ARGB_8888,true);
}
private Bitmap createForeground(int width, int height, Context con) {
Bitmap logo = null;
logo = BitmapFactory.decodeResource(con.getResources(), R.drawable.sample1);
return Bitmap.createScaledBitmap(logo,width,height,true).copy(Bitmap.Config.ARGB_8888,true);
}
}
Here are some of the screen shots that I acheive -
The code may not be that optimized, but I think it will serve your purpose. Moreover,you can use any shape or design as mask(the region that needs to be selected),ask me if you need any explanation..
You can do it like this. The example uses a Bitmap
as the source and another Bitmap
as the filter matrix. The filter bitmap has a transparent background and so has the filtered bitmap:
public Bitmap doFilter(Bitmap source, Bitmap filter) {
Bitmap filtered = Bitmap.createBitmap(source.getWidth(), source.getHeight(), source.getConfig());
Paint paint = new Paint();
Canvas canvas = new Canvas(filtered);
canvas.drawBitmap(source, 0, 0, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
canvas.drawBitmap(filter, 0, 0, paint);
return filtered;
}
For example, with this source:
And this filter:
You get this filtered image: