我一直在尝试制作一个Android应用程序,允许用户拍照并计算具有相似颜色的对象的数量,用户可以在屏幕上点击以选择他们想要的颜色。然而,我遇到了一个问题,当用户点击屏幕时,我打印出了颜色和像素的坐标,这两者看起来都很对。但当我尝试使用展开方法(从像素展开并将附近所有颜色相似的像素转换为红色),并将对象转换为完全不同的颜色(因此不会再次计数)时,程序崩溃。
这是我的代码:
package com.example.myapplication;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import android.Manifest;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.provider.MediaStore;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
private static final int CAM_PERM_CODE = 101;
private static final int CAM_REQ_CODE = 102;
private static int NumOfObj = 0;
ImageView selectedImage;
Button CameraB;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
selectedImage = findViewById(R.id.displayImageView);
CameraB = findViewById(R.id.CameraB);
CameraB.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
askCamPerm();
}
});
}
private void askCamPerm() {
if(ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, CAM_PERM_CODE);
} else {
openCam();
}
}
@SuppressLint("MissingSuperCall")
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
if (requestCode == CAM_PERM_CODE) {
if (grantResults.length < 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
openCam();
} else {
Toast.makeText(this, "Camera permission is required", Toast.LENGTH_SHORT).show();
}
}
}
private void openCam(){
Intent camera = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
NumOfObj = 0;
startActivityForResult(camera, CAM_REQ_CODE);
}
@SuppressLint("MissingSuperCall")
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
if(requestCode == CAM_REQ_CODE) {
Bitmap image = (Bitmap) data.getExtras().get("data");
selectedImage.setImageBitmap(image);
Toast.makeText(this, "Select the object you want to count", Toast.LENGTH_LONG).show();
selectedImage.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
if(motionEvent.getAction() == MotionEvent.ACTION_DOWN || motionEvent.getAction() == MotionEvent.ACTION_MOVE) {
int viewX = (int) motionEvent.getX();
int viewY = (int) motionEvent.getY();
int viewWidth = selectedImage.getWidth();
int viewHeight = selectedImage.getHeight();
Bitmap image2 = ((BitmapDrawable)selectedImage.getDrawable()).getBitmap();
int imageWidth = image2.getWidth();
int imageHeight = image2.getHeight();
System.out.println(viewX + ", " + viewWidth);
//int Offset = (viewWidth - imageWidth) / 2;
int imageX = (int)((float)(viewX) * ((float)imageWidth / (float)viewWidth));
int imageY = (int)((float)viewY * ((float)imageHeight / (float)viewHeight));
int DumpColor = image2.getPixel(imageX, imageY);
Counter(image2, DumpColor);
}
return true;
}
});
}
}
public void Counter(Bitmap image, int DumpColor) {
//Bright: 200, 192, 182
//Dim: 141, 130, 120
int height = image.getHeight();
int width = image.getWidth();
for(int col = 0; col < width; col+=5){
for(int row = 0; row < height; row += 5){
int color = image.getPixel(col, row);
if(IsDumpColor(color, DumpColor)){
NumOfObj++;
System.out.println("Counter: " + row + ", " + col);
Expand(image, row, col, DumpColor);
}
}
}
Toast.makeText(this, "The number of object is: " + NumOfObj, Toast.LENGTH_LONG).show();
}
public void Expand(Bitmap image, int row, int col, int DumpColor){
if(row == 0 || col == 0 || row == image.getHeight() || col == image.getWidth()) {
return;
}
int Pixel = image.getPixel(col, row);
System.out.println(col + ", " + row);
System.out.println("color of pixel: " + image.getPixel(col, row));
if (!IsDumpColor(Pixel, DumpColor) && Pixel == 0xFF0000){
return;
} else {
image.setPixel(col, row, 0xFF0000);
System.out.println(col + ", " + row);
System.out.println("color of pixel2: " + image.getPixel(col, row));
Expand(image, row - 1, col, DumpColor);
Expand(image, row + 1, col, DumpColor);
Expand(image, row, col - 1, DumpColor);
Expand(image, row, col + 1, DumpColor);
}
}
public boolean IsDumpColor(int color, int DumpColor){
int red = Color.red(color);
int green = Color.green(color);
int blue = Color.blue(color);
int DumpR = Color.red(DumpColor);
int DumpG = Color.green(DumpColor);
int DumpB = Color.blue(DumpColor);
if(
DumpR - red < 30 && red - DumpR < 30 &&
DumpG - green < 30 && green - DumpG < 30 &&
DumpB - blue < 30 && blue - DumpB < 30
){
return true;
}
return false;
}
}
我试图打印出像素坐标(x,y)和像素的颜色编号,但这给了我完全意想不到的结果。首先,我点击的像素是正常的,它给了我大约600900的值,但在扩展函数运行后不久,它给我15和2,颜色是-6556,我完全不知道这意味着什么。我被卡住了,因为理论上我的代码应该可以工作,我尝试过在谷歌上搜索,但没有得到任何结果。