Android PhotoView 기반 프로필 사진/원형 재단 컨트롤
흔히 볼 수 있 는 그림 재단 은 두 가지 가 있 는데 하 나 는 그림 이 고정 되 고 재단 상자 가 이동 하여 축소 되 어 재단 구역 을 확정 하 는 것 이다.초기 에 보 이 는 것 이 비교적 많 고 재단 후의 효 과 를 직접 미리 볼 수 없다 는 단점 이 있다.그리고 지금 은 재단 상자 가 고정 되 어 있 고 크기 조정 그림 을 직접 드래그 하여 재단 결 과 를 미리 볼 수 있 습 니 다.
내 가 만 든 이 컨트롤 은 후자 에 속한다.일반적으로 그림 재단 을 하 는 사고방식 은 제스처 를 감청 하고 좌 표를 얻 은 다음 에 그림 을 변형 시 키 는 것 이다.마지막 으로 재단 구역 의 좌 표를 확정 하고 비트 맵 을 재단 한 다음 에 그림 을 현지 에 저장한다.저 는 기술 이 하 얀 사람 입 니 다.제스처 를 감시 해 야 한 다 는 생각 에 머리 가 아 픕 니 다.공교롭게도 프로젝트 전에 큰 그림 을 보기 위해 유명한 제3자 사진 조회 컨트롤 인 PhotoView 를 도 입 했 습 니 다.(사용 절 차 는 이 글 을 참고 하 세 요Android PhotoView 사용 절차 인 스 턴 스 상세 설명)그래서 생각해 보 니 그림 이 변 형 될 때 까지 의 몇 단 계 를 PhotoView 에 맡 겨 서 해결 할 수 있 을 까 하 는 생각 이 들 었 습 니 다.저 는 재단 구역 뒤의 이 몇 단 계 를 확인 하 는 일 만 맡 으 면 됩 니 다.나중에 구덩이 가 몇 개 떨어져 서 게 으 름 피 우 는 것 도 쉽 지 않 았 어 요.사실은...ε=(´ο`*)))에이~
먼저 디자인 방향 을 간략하게 소개 해 야 한다.위의 그림 에서 보 듯 이 주로 두 부분 으로 나 뉘 는데 상층 부 는 가리개(재단 틀 로 도 이해 할 수 있다)로 재단 후의 효 과 를 미리 볼 수 있다.아래쪽 은 PhotoView 입 니 다.여 기 는 한 겹 더 싸 서 정사각형 으로 바 꾸 었 습 니 다.
다음은 가 려 진 코드 입 니 다.비교적 간단 합 니 다.여 기 는 군말 하지 않 겠 습 니 다.
/**
* Created by MandyLu on 2018/7/14.
*
*/
public class CircleCropView extends View {
public final int CIRCLE_MARGIN = 50;
public CircleCropView(Context context) {
super(context);
}
public CircleCropView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public CircleCropView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public CircleCropView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, widthMeasureSpec);
}
@RequiresApi(api = Build.VERSION_CODES.O)
@Override
protected void onDraw(Canvas canvas) {
canvas.save();
Path path = new Path();
Rect viewDrawingRect = new Rect();
getDrawingRect(viewDrawingRect);
float radius = viewDrawingRect.width() / 2 - CIRCLE_MARGIN;
path.addCircle(viewDrawingRect.left + radius + CIRCLE_MARGIN,
viewDrawingRect.top + radius + CIRCLE_MARGIN, radius, Path.Direction.CW);
Paint outsidePaint = new Paint();
outsidePaint.setAntiAlias(true);
outsidePaint.setARGB(151, 0, 0, 0);
canvas.clipPath(path, Region.Op.DIFFERENCE);
canvas.drawRect(viewDrawingRect, outsidePaint);
canvas.restore();
}
}
Square PhotoView 는 PhotoView 를 바탕 으로 길 이 를 바 꾸 었 을 뿐 onMeasure 방법 을 다시 쓰 면 됩 니 다.
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, widthMeasureSpec);
}
그렇다면 현재 가장 중요 한 단 계 는 PhotoView 에서 현재 그림 표시 영역의 Drawable 이나 Bitmap 를 가 져 오 는 것 입 니 다.PhotoView 의 함 수 를 대충 보 았 지만 쓸 만 한 것 을 찾 지 못 했다.첫 번 째 구 덩이 를 해결 하 는 어 리 석 은 방법 은 바로 자신 이 먹고 입 는 것 이다―원 그림 의 bitmap 를 직접 가 져 온 다음 에 PhotoView 에 게 현재 그림 의 변형 행렬 을 물 어보 고 자신 이 행렬 을 통 해 한 걸음 한 걸음 변형 하여 해당 하 는 비트 맵 을 얻 는 것 이다.생각 은 사실 문제 가 없 지만 두 번 째 구덩이 가 또 나 타 났 다.이곳 의 변형 행렬 은 제 가 최초 로 바 이 두 의 결 과 는 getSuppMatrix 입 니 다.소스 코드 는 자세히 보지 않 았 지만 구덩이 에 빠 지 는 과정 에서 제 가 관찰 한 바 에 의 하면 최신 제스처 변형 결과(불확실==다른 구덩이 가 종합 적 으로 발생 한 잘못된 결과 일 수도 있 습 니 다)라 고 추측 합 니 다.아무튼 마지막 으로 소스 코드 를 찾 아 봤 는데 getDisplayMatrix 를 사용 한 것 이 확실 합 니 다.
이 어 세 번 째 구덩이 로 구덩이 가 많 으 면 습관 이 된다.행렬 의 XY 변위 량 은 원래 그림 의 중심 보다 영역 중심 을 표시 하 는 것 이 라 고 생각 했 습 니 다.즉,크기 조정 작업 만 있 으 면 변위 가 0 이 어야 합 니 다.그러나 실제 특수 한 위치(예 를 들 어 네 개의 정점 을 가 져 오 는 것)의 재단 결 과 를 통 해 볼 때 이곳 의 XY 변위 량 은 실제 마지막 으로 구역 왼쪽 상단 의 점 이 원점(즉,원 그림 왼쪽 상단)의 위 치 를 나타 낸다.쉽게 말 하면 변위 량 을 최종 적 으로 구역 왼쪽 상단 을 나타 내 는 좌표 로 할 수 있다.
그리고 나 서 나 는 네 번 째 구 덩이 를 맞 았 다(🙂)。이 구 덩이 는 지금 뒤 돌아 보 니 간단 해서 넘 어 지지 말 았 어야 했 는데,그때 납득 하지 못 했 을 때 는 정말 당 황 스 러 웠 다.이 구덩이 의 문 제 는 바로 Matrix 의 값 은 제스처 에 기반 한 것 이다.즉,화면 픽 셀(다시 말 하면 실제 디 스 플레이 에 기반 한 그림)에 기반 한 것 이다.비트 맵 을 재단 할 때 는 원본 픽 셀 을 기반 으로 한다.그러면 여기 에는 정상 적 인 디 스 플레이 를 위해 크기 조정 비례 가 존재 합 니 다.예 를 들 어 원 도 는 3000 x 4000 입 니 다.화면 해상도 가 1080*1920 이기 때문에 실제 디 스 플레이 할 때 그림 이 축소 되 었 습 니 다.이 비율 은 9/25 입 니 다.따라서 재단 과정 에서 변위 량 을 25/9 배 더 늘 려 복원 해 야 한다.
다음은 커팅 부분의 핵심 코드 입 니 다.
fun cropImage(){
var degree = ImageUtils.readPictureDegree(imagePath)
var bitmap = ImageUtils.getRotatedBitmap(BitmapFactory.decodeFile(imagePath),degree)
var width: Int = 0
var startX: Int = 0
var startY: Int = 0
if (bitmap.width < bitmap.height){
startY = (bitmap.height - bitmap.width) / 2
width = bitmap.width
}else{
startX = (bitmap.width - bitmap.height) / 2
width = bitmap.height
}
var matrix = Matrix()
photo_preview.getDisplayMatrix(matrix)// , scaleX translationX
var values = FloatArray(9, {0.0f})
matrix.getValues(values)
var expWidth = Math.round(bitmap.width * values[0])// x
var expHeight = Math.round(bitmap.height * values[4])// y
var bitmap1 = Bitmap.createScaledBitmap(bitmap, expWidth, expHeight, false)
val ratio = width * 1.0f / photo_preview.width
startX = Math.round(startX * values[0] - values[2] * ratio)
startY = Math.round(startY * values[4] - values[5] * ratio)
var bitmap2 = Bitmap.createBitmap(bitmap1, startX, startY, width, width, null, false)
saveImage(bitmap2)
}
여기에 또 몇 개의 작은 구덩이 가 있 으 니 설명해 야 한다.bitmap 를 읽 을 때 각 도 를 주의해 야 합 니 다.이것 은 내 가 로 컬 사진 과 인터넷 사진 을 재단 할 때 발견 한 것 이 고,어떤 것 은 바로 90 도 돌 았 다.휴대 전화 마다 다 르 기 때문에 안전 을 위해 서 는 사진 의 EXIF 정보 에서 회전 이 필요 한 각 도 를 얻 은 다음 에 더 처리 해 야 한다.
나 는 최종 적 으로 정사각형 을 표시 하고 scale Type 을 선택 한 것 은 centerCrop 이기 때문이다.그래서 기본 값 은 중간 에 있 는 것 을 보 여 주 는 것 입 니 다.그래서 감축 할 때의 원점 도 정사각형 의 왼쪽 상단 부터 시작 해 야 한다.여 기 는 두 가지 상황 을 계산 하 는 원점 좌표 입 니 다.
var startX: Int = 0
var startY: Int = 0
if (bitmap.width < bitmap.height){
startY = (bitmap.height - bitmap.width) / 2
width = bitmap.width
}else{
startX = (bitmap.width - bitmap.height) / 2
width = bitmap.height
}
크기 조정 작업 후 원점 좌표 도 이에 따라 바 뀌 고 해당 하 는 크기 조정 비율 을 곱 한 다음 에 해당 하 는 변위 량 에 따라 재단 구역 의 위 치 를 확정 합 니 다.매트릭스 로 직접 변형 하려 고 했 는데 실 패 했 습 니 다(원인 불명).다른 재단 컨트롤 원본 코드 를 보고 createcaledBitmap 를 사용 하여 방법 을 결정 합 니 다.
마지막 으로 검토 해 야 한다.잔 머리 를 굴 려 서 가 까 운 길 로 가 려 고 했 는데 소스 코드 에 익숙 하지 않 아서 구 덩이 를 만 났 을 때 도 블랙박스 로 만 여 길 수 밖 에 없 었 다.끊 임 없 는 실험 을 통 해 문제 의 소 재 를 추측 할 수 있 을 뿐,오히려 더 많은 시간 을 들 여 얻 는 것 보다 잃 는 것 이 많다.앞으로 시간 이 있 을 때 는 소스 코드 를 꼼꼼 히 연구 하고 원리 적 으로 문 제 를 해결 해 야 합 니 다(*~커튼)~
마지막 으로,몇 명의 블 로 거들 의 사심 없 는 공유 에 감 사 드 립 니 다.이에 감 사 드 립 니 다~
>>>Android Bitmap 에서 흔히 볼 수 있 는 몇 가지 동작:크기 조정,재단,회전,오프셋
>>>Android ImageCropper 사각형 원형 재단 상자
>>>Android 재단 그림 이 원형 그림 의 실현 원리 와 코드
총결산
이상 은 이 글 의 전체 내용 입 니 다.본 논문 의 내용 이 여러분 의 학습 이나 업무 에 어느 정도 참고 학습 가치 가 있 기 를 바 랍 니 다.궁금 한 점 이 있 으 시 면 댓 글 을 남 겨 주 셔 서 저희 에 대한 지지 에 감 사 드 립 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Android PhotoView 기반 프로필 사진/원형 재단 컨트롤그리고 나 서 나 는 네 번 째 구 덩이 를 맞 았 다(🙂)。이 구 덩이 는 지금 뒤 돌아 보 니 간단 해서 넘 어 지지 말 았 어야 했 는데,그때 납득 하지 못 했 을 때 는 정말 당 황 스 러 웠 다.이 구덩이 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.