When applying Roboflow to Android Studio, Error Response: {“message”:“Could not load input image. Cause: Malformed base64 input image.”} and Error Response: {“message”:“Internal error.”} occurs repeatedly, how can I resolve this?
This is mainactiviy code
public class MainActivity extends AppCompatActivity {
private static final int REQUEST_IMAGE_CAPTURE = 672;
private String imageFilePath;
private Uri photoUri;
private TextView resultTextView;
private static final String TAG = "MainActivity";
PermissionListener permissionlistener = new PermissionListener() {
@Override
public void onPermissionGranted() {
Toast.makeText(MainActivity.this, "권한이 허용됨", Toast.LENGTH_SHORT).show();
}
@Override
public void onPermissionDenied(List<String> deniedPermissions) {
Toast.makeText(MainActivity.this, "권한이 거부됨" + deniedPermissions.toString(), Toast.LENGTH_SHORT).show();
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
resultTextView = findViewById(R.id.resultTextView);
TedPermission.with(this)
.setPermissionListener(permissionlistener)
.setRationaleMessage("카메라 권한이 필요합니다.")
.setDeniedMessage("거부하셨습니다.")
.setPermissions(Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA)
.check();
findViewById(R.id.btn_capture).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (intent.resolveActivity(getPackageManager()) != null) {
File photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException e) {
e.printStackTrace();
}
if (photoFile != null) {
photoUri = FileProvider.getUriForFile(getApplicationContext(), getPackageName() + ".provider", photoFile);
intent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);
startActivityResult.launch(intent);
}
}
}
});
}
ActivityResultLauncher<Intent> startActivityResult = registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(),
new ActivityResultCallback<ActivityResult>() {
@Override
public void onActivityResult(ActivityResult result) {
if (result.getResultCode() == Activity.RESULT_OK) {
Bitmap bitmap = BitmapFactory.decodeFile(imageFilePath);
ExifInterface exif = null;
try {
exif = new ExifInterface(imageFilePath);
} catch (IOException e) {
e.printStackTrace();
}
int exifOrientation;
int exifDegree;
if (exif != null) {
exifOrientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
exifDegree = exifOrientationToDegrees(exifOrientation);
} else {
exifDegree = 0;
}
((ImageView) findViewById(R.id.iv)).setImageBitmap(rotate(bitmap, exifDegree));
// 이미지 분석
analyzeImage(bitmap);
}
}
});
private File createImageFile() throws IOException {
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
imageFilePath = image.getAbsolutePath();
Log.d(TAG, "Image File Path: " + imageFilePath);
return image;
}
private int exifOrientationToDegrees(int exifOrientation) {
if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_90) {
return 90;
} else if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_180) {
return 180;
} else if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_270) {
return 270;
}
return 0;
}
private Bitmap rotate(Bitmap bitmap, int exifDegree) {
Matrix matrix = new Matrix();
matrix.postRotate(exifDegree);
return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
}
private static final String ROBOFLOW_API_KEY = "6J8cv5JupaMhqVVk3mtz";
private static final String ROBOFLOW_MODEL_ID = "alcohol-datasets1";
private void analyzeImage(Bitmap bitmap) {
new Thread(() -> {
try {
if (bitmap == null) {
Log.e(TAG, "Bitmap is null");
return;
}
Bitmap resizedBitmap = resizeBitmap(bitmap, 640, 640);
String imageBase64 = bitmapToBase64(resizedBitmap);
if (imageBase64 == null || imageBase64.isEmpty()) {
Log.e(TAG, "Image data is null or empty");
return;
}
String uploadURL = "https://detect.roboflow.com/" + ROBOFLOW_MODEL_ID + "/1?api_key=" + ROBOFLOW_API_KEY;
JSONObject jsonObject = new JSONObject();
jsonObject.put("image", imageBase64);
String jsonInputString = jsonObject.toString();
Log.d(TAG, "JSON Payload: " + jsonInputString);
HttpURLConnection connection = (HttpURLConnection) new URL(uploadURL).openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/json; utf-8");
connection.setDoOutput(true);
Log.d(TAG, "Sending request to " + uploadURL);
try (OutputStream os = connection.getOutputStream()) {
byte[] input = jsonInputString.getBytes("utf-8");
os.write(input, 0, input.length);
}
int responseCode = connection.getResponseCode();
Log.d(TAG, "Response Code: " + responseCode);
BufferedReader br;
if (responseCode == HttpURLConnection.HTTP_OK) {
br = new BufferedReader(new InputStreamReader(connection.getInputStream(), "utf-8"));
} else {
br = new BufferedReader(new InputStreamReader(connection.getErrorStream(), "utf-8"));
}
StringBuilder response = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
response.append(line.trim());
}
br.close();
Log.d(TAG, "Response: " + response.toString());
if (responseCode == HttpURLConnection.HTTP_OK) {
JSONObject jsonResponse = new JSONObject(response.toString());
JSONArray predictions = jsonResponse.getJSONArray("predictions");
if (predictions.length() > 0) {
JSONObject prediction = predictions.getJSONObject(0);
String resultLabel = prediction.getString("class");
int resultClassId = prediction.getInt("class_id");
runOnUiThread(() -> {
String result = "Class: " + resultLabel + ", Class ID: " + resultClassId;
resultTextView.setText(result);
});
Log.d(TAG, "Result: Class: " + resultLabel + ", Class ID: " + resultClassId);
} else {
Log.d(TAG, "No predictions found.");
}
} else {
Log.e(TAG, "Error Response: " + response.toString());
runOnUiThread(() -> Toast.makeText(MainActivity.this, "Error: " + response.toString(), Toast.LENGTH_LONG).show());
}
} catch (Exception e) {
e.printStackTrace();
Log.e(TAG, "Error: " + e.getMessage());
runOnUiThread(() -> Toast.makeText(MainActivity.this, "네트워크 오류", Toast.LENGTH_SHORT).show());
}
}).start();
}
private Bitmap resizeBitmap(Bitmap bitmap, int newWidth, int newHeight) {
return Bitmap.createScaledBitmap(bitmap, newWidth, newHeight, true);
}
private String bitmapToBase64(Bitmap bitmap) {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, byteArrayOutputStream); // JPEG 포맷으로 압축
byte[] byteArray = byteArrayOutputStream.toByteArray();
String base64String = Base64.encodeToString(byteArray, Base64.NO_WRAP); // NO_WRAP 사용
Log.d(TAG, "Base64 String Length: " + base64String.length());
Log.d(TAG, "Base64 String Sample: " + base64String.substring(0, 50)); // 첫 50자 출력
// 디코딩 테스트
byte[] decodedBytes = Base64.decode(base64String, Base64.DEFAULT);
Bitmap decodedBitmap = BitmapFactory.decodeByteArray(decodedBytes, 0, decodedBytes.length);
if (decodedBitmap == null) {
Log.e(TAG, "Decoded Bitmap is null");
} else {
Log.d(TAG, "Decoded Bitmap is valid");
}
return base64String;
}
}