구현할 내용
- 이미지 업로드시 해당 이미지에 적힌 글자를 text로 변환
- 변환된 내용을 firebase realtime database에 저장
- 7. firebase에서 이미지 불러오기 에서 코드 수정
사용한 API : https://github.com/rmtheis/tess-two
사전 학습 언어모델 : https://github.com/tesseract-ocr/tessdata
dependencies {
implementation 'com.rmtheis:tess-two:9.1.0'
}
private fun uploadImageTOFirebase(uri: Uri) {
val storage: FirebaseStorage = FirebaseStorage.getInstance()
val fileName = "IMAGE_${SimpleDateFormat("yyyymmdd_HHmmss").format(Date())}_.png"
val imagesRef = storage.reference.child("images/").child(fileName)
imagesRef.putFile(uri)
.addOnSuccessListener {
// OCR 처리를 위한 이미지 파일 생성
val imageFile = File(applicationContext.cacheDir, "temp_image.jpg")
uri.toFile(applicationContext, imageFile)
// OCR 실행
val recognizedText = ocrImage(imageFile)
// firebase DB에 OCR 결과 업로드
val databaseRef = database.getReference("ocr_results")
val key = databaseRef.push().key ?: ""
val result = hashMapOf(
"image_url" to imagesRef.path,
"text" to recognizedText
)
databaseRef.child(key).setValue(result)
}
private fun ocrImage(imageFile: File): String {
val baseApi = TessBaseAPI()
val datapath = "${applicationContext.filesDir}/tesseract/"
val lang = arrayOf("kor", "eng")
val trainedDataPaths = lang.map { "$it.traineddata" }
for (trainedDataPath in trainedDataPaths) {
// traineddata 파일의 경로
val trainedDataFile = File("$datapath/tessdata/$trainedDataPath")
// traineddata 파일이 존재하지 않는 경우, assets 폴더에서 복사해옴
if (!trainedDataFile.exists()) {
try {
val dir = File("$datapath/tessdata/")
if (!dir.exists()) {
dir.mkdirs()
}
val inputStream = applicationContext.assets.open(trainedDataPath)
val outputStream = FileOutputStream(trainedDataFile)
inputStream.copyTo(outputStream)
inputStream.close()
outputStream.close()
} catch (e: IOException) {
e.printStackTrace()
}
}
}
baseApi.init(datapath, lang.joinToString("+"))
baseApi.setImage(imageFile)
val recognizedText = baseApi.utF8Text
baseApi.end()
Log.d("OCR Result", recognizedText) // OCR 결과를 Log로 출력
return recognizedText
}
private fun Uri.toFile(context: Context, file: File): File {
context.contentResolver.openInputStream(this).use { input ->
file.outputStream().use { output ->
input?.copyTo(output)
}
}
return file
}
OCR 후에 내가 원하는 부분만 key 별로 value를 저장하고 싶기 때문에, 이미지 자르기 기능을 넣어서 정보를 좀더 얻기 쉽게 만들 예정
이것만으로는 명확한 분류가 어려울것 같아서 더 고민해봐야겠다.