전체 포스팅에 대한 간략한 소개를 하자면 사용자의 서명정보를 받아서 이미지 문서로 저장을 하려고 하는데 실 사용자가 서명을 너무 작게 하였을 경우 서명된 이미지 영역을 인식하여 이미지를 확대 저장하기 위함입니다.
* 화면 레이아웃
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/border_sign" />
<!-- 서명 입력 View -->
<com.divyanshu.draw.widget.DrawView
android:id="@+id/draw_sign"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="5dp" />
<!-- 서명 텍스트-->
<TextView
android:id="@+id/txt_dialog_gray_sign"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="5dp"
android:gravity="center"
android:text="서명해주세요."
android:textColor="#a0a0a0"
android:textSize="55sp"
android:textStyle="bold" />
</FrameLayout>
* setBitmapSign :
서명된 이미지 정보를 Android Bitmap 으로 가져온 후 서명된 영역만 추출 변경하고 반환하는 함수
public ImageView setBitmapSign(Bitmap bitmap) {
ImageView iv = ((ImageView) findViewById(allSignatureLayoutId.getImgSign()));
// 추출 이미지 중앙정렬 및 영역추출
Bitmap map = makeAutoFitableBitMap(bitmap);
// bitmap 배경 투명처리
map = makeTransparent(map);
iv.setImageBitmap(map);
return iv;
}
전체 라이프사이클이 조금 다르게 구성이 되어져 있어서 단순하고 조금 수정을 진행하였습니다.
* makeTransparent
서명된 영억 이외의 부분 배경 정보를 투명하게 처리
/*
* Bitmap 하얀색 배경을 투명하게 변환
*/
private Bitmap makeTransparent(Bitmap bit) {
int width = bit.getWidth();
int height = bit.getHeight();
Bitmap myBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
int[] allpixels = new int[myBitmap.getHeight() * myBitmap.getWidth()];
bit.getPixels(allpixels, 0, myBitmap.getWidth(), 0, 0, myBitmap.getWidth(), myBitmap.getHeight());
myBitmap.setPixels(allpixels, 0, width, 0, 0, width, height);
for (int i = 0; i < myBitmap.getHeight() * myBitmap.getWidth(); i++) {
if (allpixels[i] == Color.WHITE) { // 하얀색을 투명하게 변환
allpixels[i] = Color.alpha(Color.TRANSPARENT);
}
}
myBitmap.setPixels(allpixels, 0, myBitmap.getWidth(), 0, 0, myBitmap.getWidth(), myBitmap.getHeight());
return myBitmap;
}
* makeAutoFitableBitMap
실제 서명이 완료된 이미지 bitmap에서 역영추출하여 새료운 bitmap 으로 재생성
/*
* Bitmap 서명 자동 가운데 정렬 + 크기조절
*/
private Bitmap makeAutoFitableBitMap(Bitmap bit){
int width = bit.getWidth();
int height = bit.getHeight();
//변경될 이미지를 담을 새로은 비트맵을 생성
Bitmap myBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
int[] allpixels = new int[myBitmap.getHeight() * myBitmap.getWidth()];
bit.getPixels(allpixels, 0, myBitmap.getWidth(), 0, 0, myBitmap.getWidth(), myBitmap.getHeight());
myBitmap.setPixels(allpixels, 0, width, 0, 0, width, height);
// 1. 비트맵 서명부분만 가지고 와서 가운데 정렬 실행
int minX = bit.getWidth();
int minY = bit.getHeight();
int maxX = 0;
int maxY = 0;
int currX = 0;
int currY = 0;
// 1-1. 서명이 있는 픽셀의 2차원 최소X, 최대X, 최소Y, 최대Y 좌표 구하기
for (int i = 0; i < myBitmap.getHeight() * myBitmap.getWidth(); i++) {
// 서명정보가 있는 픽셀일 경우
if (allpixels[i] != Color.WHITE) {
currY = i / bit.getWidth();
currX = i - (currY * bit.getWidth());
if(minX > currX){ // 서명의 최소 X좌표
minX = currX;
}
if(maxX < currX){ // 서명의 최대 X좌표
maxX = currX;
}
if(minY > currY){ // 서명의 최소 Y좌표
minY = currY;
}
if(maxY < currY){ // 서명의 최대 Y좌표
maxY = currY;
}
if(minX < 11) minX = 11;
if(maxX < 11) maxX = 11;
}
}
// 서명 주위에 들어갈 패딩
int padding = 10;
minX = minX - padding;
maxX = maxX + padding;
minY = minY - padding;
maxY = maxY + padding;
// 1-2. 서명이 새로 복사될 전체 2차원 width, height 크기 구하기
int resWidth = bit.getWidth() - ( bit.getWidth() - maxX ) - minX;
int resHeight = bit.getHeight() - ( bit.getHeight() - maxY ) - minY;
int[] resPixels = new int[resWidth * resHeight];
int resCpCnt = 0;
// 1-3. 기존 픽셀에서 서명부분의 좌표의 픽셀들만 복사하기
for (int i = 0; i < myBitmap.getHeight() * myBitmap.getWidth(); i++) {
currY = i / bit.getWidth();
currX = i - (currY * bit.getWidth());
// 좌표가 최소Y ~ 최대Y && 최소X ~ 최대X 좌표 사이에 있는경우
if(minY <= currY && maxY > currY){
if(minX <= currX && maxX > currX){
resPixels[resCpCnt] = allpixels[i]; // 좌표안의 픽셀 복사
resCpCnt++;
}
}
}
// 1-4. 복사한 서명부분의 픽셀들만 비트맵으로 만들기
Bitmap resBitmap = Bitmap.createBitmap(resWidth, resHeight, Bitmap.Config.ARGB_8888);
resBitmap.setPixels(resPixels, 0, resWidth, 0, 0, resWidth, resHeight);
// 2. 비트맵 리사이징
// maxResolution = 가로 또는 세로 비율에 맞추어 이미지 리사이징
resBitmap = resizeBitmapImage(resBitmap, 250);
return resBitmap;
}
참 아릅답게 잘 나왔다 ㅎㅎㅎㅎ
'개발 > 안드로이드' 카테고리의 다른 글
안드로이드 기술 면접에 좋을 자료 (0) | 2020.11.19 |
---|---|
Bitmap 에서 백그라운드 투명처리 (2) | 2020.11.16 |
Activity 라이프사이클 맛보기 정리 (0) | 2020.10.26 |