최근 페이스북 측에서 업데이트하라고 리포트가 와서 로그인 모듈을 업데이트 하는 데 빌드 에러가 떴습니다.


Exception while processing task java.io.ioexception: can't write ~ ~ Duplicate zip entry com.google.zxing~ 



정확히는 기억안나고 대충 이런 내용이었는 데, Facebook 라이브러리가 업데이트되면서 따로 사용 중인 Zxing라이브러리와 중복되는 부분이 있는 것 같습니다. 


implementation ('com.facebook.android:facebook-android-sdk:4.38.1') { exclude group: 'com.google.zxing' } 


이렇게 exclude 부분을 추가해주면 정상적으로 빌드되는 것을 확인하실 수 있습니다. 


추가로, 현재 4.39.0까지 나왔는 데 iOS쪽에서 로그인 버튼이 안눌러지는 버그가 발견되었다고 합니다. 

4.39.0으로 업데이트 하시는 분들은 꼭 확인해보시고 적용하시길 바랍니다.

   Databinding을 활용하여 작업하는 중 다른 프로젝트를 동시에 켜서 실행하다가 다시 빌드했더니 생긴 문제입니다.

처음엔 generated 폴더에서 에러가 나서 Invalid Caches / Restart를 실행하였으나 실패했고, 재부팅을 하여도 같은 결과가 나왔습니다.


 LoggedErrorException found data binding errors


   위와 같은 문제가 생길 시 프로젝트 하위에 있는 .idea와 .gradle을 삭제 후 Clean-build를 하시면 다시 정상적으로 동작하는 것을 보실 수 있습니다.




출처 : https://stackoverflow.com/questions/44594475/listener-binding-cannot-find-the-setter

  오늘 인수인계 받은 코드를 안드로이드 스튜디오 내에서 버전업하다가 2시간을 버리게 만든 에러가 있었습니다. 



unable to resolve dependency for could not resolve multidex 1.0.2


  메소드가 64k이상인 경우 빌드가 가능하도록 도와주는 multidex의 에러인 데.. 아무리 찾아보고 해결 방법을 적용해봐도 수정이 안돼서 고생하다가 겨우 찾았습니다. 스택오버플로우나 기타 개발 블로그들에서 제시한 것들 중 다 안되는 분은 적용해보시면 좋을 것 같습니다.


  생각보다 간단합니다. 그냥 build.gradle에



dependencies {
   compile 'com.android.support:multidex:1.+'
}


넣어주면 끝입니다.

비슷하게 제시한 해결법이 multidex:1.+ 대신 multidex:1.0.2를 넣는 것인데.. 

저의 경우는 실패했고 예전에 비슷한 케이스가 생각나서 1.+로 바꿔주니 됐습니다.

가끔 구글에 검색을 해봤는 데 최근에도 Tesseract를 사용한 OCR의 인식률을 높힐 수 있는 방법에 대한 포스팅이 없는 것 같아서 

인식률을 높히기 위해 고생 중인 Tesseract 사용자 분들을 위해 제 경험을 토대로 알려드리고자 합니다.


시작하기에 앞서, 이번 포스팅은 제가 Tesseract를 약 4개월동안 사용하고 낸 결론을 바탕으로하며 모바일 기준으로 적는 것임을 알려드립니다.



1. 모바일 Tesseract 활용을 위한 프로세스


모바일을 통해 OCR을 돌린다는 것은 PC에서 돌리는 것과 활용의 폭 차이가 매우 큽니다.

PC처럼 이미 가진 이미지 파일을 불러와서 OCR을 실행하는 것이 아니라 인쇄된 문서와 같은 것을 카메라로 촬영하여 즉시 텍스트로 출력시킬 수 있기 때문입니다. 이러한 활용 방식은 이미 많이 알려져있는 방식이지만, 아무래도 카메라로 촬영해서는 인식률 차이가 엄청나게 차이나서 많이들 고민하시는 부분입니다.


이 부분을 해결하기 위해서는 영상처리 기술이 필요하게 되는 데, 이중 가장 중요한 기법을 하나 소개하겠습니다.

바로 'Perspective Transform' 이라는 기술입니다.

자세히 이해할 필요는 없기 때문에 그냥 어떤 기술인지 알 수 있도록 링크를 하나 걸어드리겠습니다.


Perspective Transform 소개


간단히 줄여서 말씀드리자면 눕혀져있는 문서이미지를 정확하게 펴는 기술로, 캠스캐너라는 앱에서 체험하실 수 있는 기술입니다.

사용해보지 않으신 분들은 무료버전이 존재하니 한 번 설치해서 A4용지를 촬영해보시기를 권장합니다.


OpenCV에서 getPerspectiveTransform 함수를 활용하여 기능을 구현할 수 있는 데, 요즘 안드로이드 스튜디오에서 워낙 NDK개발을 쉽게할 수 있도록 만들어 놓기도 하였고 Android 버전의 OpenCV도 나왔기 때문에 영상처리라고 겁먹지 마시고 구현해보려고 노력하신다면 충분히 기본적인 기능 구현은 가능합니다.


이후 만약 문서에 깔끔하게 글자만 있는 게 아니라 잡영이나 홀로그램 등, OCR 인식에 방해할만한 요소가 있다면 원래대로라면 이를 없애줄 전처리가 필요하지만 그 부분은 영상처리의 전문지식을 요하는 터라 그나마 보완해줄 수 있는 방법으로 GrayScale을 Tesseract 실행 전에 이미지에 적용해주는 방법이 있습니다.



요약해드리자면

Perspective Transform - GrayScale(외 전처리 기술) - Tesseract - (후처리)순입니다. 

별거 없어 보이지만 매우 큰 차이를 보이고, 실제 기업들도 OCR 관련 기술들은 비슷한 프로세스를 따르고 있으니 시도해보시면 좋을 것 같습니다.



2. Tesseract에서 권장하는 환경


1) 폰트 크기 약 11-13pt 사이

2) 300dpi 이상의 이미지

3) 글자가 반듯하게 나오도록 Rotation

4) 글자 외의 Table이나 Border 삭제

5) 문장별로 적절하게 분할



다음 포스팅은 이번 포스팅에서 소개한 프로세스를 직접 실행하는 것을 보여드리는 것으로 할 것 같습니다.

이미 만들어 둔게 있긴 한데 저도 좀 정리를 해야할 것 같아서 언제 업데이트 해드릴지는 잘 모르겠네요.. ㅠㅠ



참고

1) Perspective Transform 소개 : http://miatistory.tistory.com/5

2) Tesseract 권장 환경 : https://github.com/tesseract-ocr/tesseract/wiki/ImproveQuality


오늘도 공부 중에 에러가 떠서 기록 겸 남겨둡니다.



Linker command failed with exit code 1 



에러명은 위와 같고, 해결 방법은 


에러가 나는 프로젝트의 Build Settings로 들어가셔서 Architectures에 있는 $(ARCHS_STANDARD)를 $(ACRHS_STANDARD_32_BIT)로 바꿔주시면 됩니다.

원인은 build에서 32bit를 지원하지 못하는 버그 때문에 구형 디바이스에서 에러가 뜨는 것이였습니다.

하지만 찾아보니 위 에러에 대한 해결법이 다양한 것으로봐서 이 경우에만 출력되는 에러메시지는 아닌 것 같습니다.


이런 방법도 있다 라고 참고용으로 알아두시면 좋을 것 같습니다.



ps. 제가 며칠전에 겪은 에러라 결국 해결방법을 적은 출처를 찾지 못했습니다. 나중에 찾으면 꼭 올리도록 하겠습니다.ㅠㅠ

하는 김에 이번엔 aar 파일을 만들어보겠습니다.


aar파일을 만들기 원하는 프로젝트의 build.gradle에 들어가셔서, 아래 소스를 써주시면 됩니다.

buildTypes {

      release {

            libraryVariants.all { variant ->

                  variant.outputs.each { output ->

                        def outputFile = output.outputFile

                        if (outputFile != null && outputFile.name.endsWith('.aar')) {

                              def fileName = "CreabySampleLibrary.aar"

                              output.outputFile = new File(outputFile.parent, fileName)

                        }

                  }

            }

       }


혹시 오타 났을까봐;; 이미지로도 올리겠습니다.



이렇게 작성 후 빌드하시면 build -> output 폴더가 생성되면서 aar파일이 있을겁니다.

그걸 그대로 사용하시면 됩니다.

이번엔 라이브러리 프로젝트를 만들어보겠습니다.

기능에 따라 프로젝트의 분리가 필요하거나 라이브러리를 만들 때 사용하는데요.

매우 쉽게 만드실 수 있을겁니다.


구현 환경은 Android Studio 2.3.3 Mac버전 입니다.



기본적 바탕은 그냥 일반적인 프로젝트를 만들어주시면 됩니다.

Empty Activity를 선택하시고요.

.

.

.

만드셨으면 이제 라이브러리 프로젝트로 변경해보겠습니다.


1. 메니페스트에 들어가서 아래와 같이 package명만 놔두고 전부 지워줍니다.




2. build.gradle에 들어가서 apply:plugin의 com.android.application을 com.android.library로 바꿔주시고, applicationId를 지워줍니다.

끝났습니다.

참 쉽죠?


적용할 땐 적용하고 싶은 어플리케이션 프로젝트에서 File -> New -> Import Module에 들어가셔서 추가해주시고, File -> Project Structure 들어가셔서 좌측 탭에 있는 Modules에서 어플리케이션 프로젝트 -> Dependencies -> + 누르셔서 해당 프로젝트를 추가해주시면 됩니다.




자꾸 까먹는 데 구글링하면 방식이 여러가지인 것 같아서 그냥 기록 겸 올립니다.

이런 기본적인 것도 자주 까먹는 걸 보면 아직 전 멀은 것 같네요 ㅠㅠ


적용하려는 프로젝트의 build.gradle 에서


repositories {

      flatDir {

         dirs 'libs'

      }

}


이렇게 라이브러리 경로를 설정해주신 후, (폴더가 없으시면 없으시면 src와 build폴더가 있는 경로에 직접 폴더를 만드시면 됩니다.)



dependencies {

      compile(name: 'HelloWrold', ext: 'aar') 

}


이렇게 해주면 끝납니다.


추가 (2017. 11. 02) : 라이브러리를 추가하면 꼭 Clean Project와 Build를 해주셔야합니다. 안하면 적용이 안되는 문제가 생길 수 있습니다.


참 쉽죠?

근데 전 자꾸 까먹네요..

오늘 남들 다 Swift공부하는 시대에 Objective-C를 공부하기 시작했습니다.

까다롭기로 소문난 iOS라 어느 정도 걱정을 하긴 했는 데 Xcode사용법에서부터 하루를 날렸네요..


돌고돌아 본격적으로 코딩 시작하고나서 만난 첫 에러는 아래와 같습니다.


EXC_BAD_ACCESS (code=2, address=주소값) 



.. 구글링을 해봤는 데 이것 저것 설정을 바꾸라는 말부터 NSZombie라는 웬지 써선 안될 것 같은 명칭의 기능을 써야한다고 나오길래

영 마음에 안들어서 다른 방법이 없을까하고 찾던 중 답을 찾았습니다. 저같은 경우는 self.a.b 처럼 중복으로 들어가서 콜했을 때 나온 문제였는 데,

이처럼 처리했을 때 a부분의 처리가 늦어지면 무한루프가 만들어져서 생기는 문제라고 합니다.


수정 방법은 self를 빼고 _a.b 로 처리하면 되네요.. 


제가 Objective-C는 정말 1도 모를 뿐더러 기록을 위해 올려놓은지라 출처를 직접 읽어보시는 게 좋을 것 같습니다.



출처

https://stackoverflow.com/questions/14916332/how-do-i-debug-exc-bad-access-code-2-while-using-arc

안드로이드 개발하면서 다들 한 번쯤 봤을 에러일겁니다.


java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader 



so파일을 사용할 때 연동이 안된다고 뜨는 에러인데요.

jniLibs에 종류별로 모두 들어가있어야할 so파일이 어딘가 비어있는 데 모바일 디바이스 기종 상 so파일이 없는 곳을 참조하려고 해서 생기는 문제입니다. 이럴 때는 딱 두 부분만 추가해주면 됩니다.


gradle.properties에 가셔서 android.useDeprecatedNdk=true를 써주시고

so파일을 사용하는 프로젝트의 gradle에 가셔서 defaultConfig 안에


defaultConfig {
   ndk {
      abiFilters 'arm64-v8a', 'armeabi'
   }
}


이런 식으로 해당 so파일이 있는 폴더만 적어주시면 됩니다.


ABI 문제로 인해 디바이스 충돌 사례가 자주 발생하니 앱 개발 시 다양한 NDK를 사용한다면 지원하는 ABI를 미리 정하고 모두 통일시켜서 같은 ABI만 사용하셔야 위와 같은 안봐도 될 불필요한 에러를 발생시키지 않으니 꼭 잘 확인하고 개발하시는 것이 좋습니다.



추가 (2017.11.01) : so파일이 두 종류가 있는 데 하나는 armeabi, armeabi-v7a가 있고 하나는 armeabi, arm64-v8a가 있는 상황인 경우, 둘 다 사용하기 위해 armeabi, armeabi-v7a, arm64-v8a를 적으면 Crash가 납니다. 모두 있는 경우만 사용 가능하니 유의해주세요.


참고

해결법 https://stackoverflow.com/questions/37884769/unsatisfiedlinkerror-dalvik-system-pathclassloader

설명 https://developer.android.com/studio/projects/add-native-code.html?hl=ko

+ Recent posts