안 드 로 이 드 이미지 로 딩 프레임 워 크 상세 설명 Fresco 기본 사용(2)
학습 내용:
1.진도 표
2.크기 조정
3.ControllerBuilder,ControllerListener,PostProcesser,Image Request
4.점진 적 JPEG 와 움 직 이 는 그림 표시
최근 이틀 동안 Fresco 의 공식 문 서 를 보면 차이 가 많 지 않 은 셈 이다.Fresco 의 기본 원리 와 okHttp 등 라 이브 러 리 를 결합 하여 어떻게 사용 하 는 지 에 대한 문제 만 남 았 다.비록 공식 문서 가 제시 한 기능 이 비교적 많 지만 예 를 들 어 사용자 정의 View,미리 보기 그림 표시 등 이다.이런 것들 은 나 도 대체적으로 대강 을 보 았 는데 실제 수요 가 그렇게 높 은 요구 가 없 을 것 이 라 고 생각한다.그래서 어떤 것들 은 제 가 여기 서 소개 하지 않 겠 습 니 다.상세 한 상황 은 공식 문 서 를 참고 할 수 있 습 니 다.저 는 사용 상황 이 비교적 많은 기능 에 대해 간단 한 소 개 를 할 뿐 입 니 다.
1.진도 표
진도 바 도 Fresco 의 한 기능 이 라 고 할 수 있 습 니 다.Fresco 내부 자체 에 Progress BarDrawable 류 를 제 공 했 습 니 다.효 과 는 사각형 의 파란색 진도 바 입 니 다.그림 이 로드 상태 에 있 을 때 진도 바 는 따라 로드 됩 니 다.그림 로드 가 끝 난 후에 진도 바 도 사라 집 니 다.그러나 이 진 도 는 실시 간 으로 업데이트 되 는 것 이 아 닙 니 다.만약 우리 가 정확 한 로드 진 도 를 원한 다 면,우 리 는 내부 의 방법 을 다시 써 야 한다.
class CustomProgressBar extends Drawable{
@Override
protected boolean onLevelChange(int level) {
//doSomething
return super.onLevelChange(level);
}
}
사용자 정의 진도 바 는 onLevelChange 방법 을 실현 해 야 합 니 다.여기 서 간단 한 소개 만 할 수 있 습 니 다.진도 바 를 사용자 정의 하려 면 Progress BarDrawable 을 참조 하여 진도 바 를 다시 쓸 수 있 습 니 다.개인 적 으로 이 기능 이 별로 라 고 생각 합 니 다.그림 을 불 러 올 때 진도 바 를 사용 하 는 것 보다.ProgressBarImage 속성 을 사용 하여 그림 을 불 러 올 때 진행 그림 을 설정 하고 회전 속성 도 지원 합 니 다.2.크기 조정
DraweeView 의 크기 조정 과 ImageView 의 크기 조정 유형 은 기본적으로 같 습 니 다.fitXY,centerCrop.유일 하 게 ImageView 와 차이 가 있 는 것 은 matrix 속성 을 지원 하지 않 지만 matrix 속성 대신 focusCrop 속성 을 추 가 했 습 니 다.속성 을 설정 할 때,xml 는 fresco:actualcale Type 을 사용 하여 DraweeView 의 크기 조정 속성 을 설정 하거나 GenericDraweeHierarchy 속성 을 사용 하여 설정 합 니 다.
GenericDraweeHierarchyBuilder progressHierarchyBuilder = new GenericDraweeHierarchyBuilder(getResources());
GenericDraweeHierarchy progressHierarchy = progressHierarchyBuilder
.setProgressBarImage(new ProgressBarDrawable(), ScalingUtils.ScaleType.CENTER_INSIDE)
.build();
progressImageDraweeView.setHierarchy(progressHierarchy);
setScale Type()이나 xml 에서 android:scale Type 을 사용 하지 마 십시오.크기 조정 속성 을 설정 하 는 것 은 잘못 되 었 습 니 다.공식 적 으로 matrix 대신 focusCrop 을 제시 하 는 것 은 일리 가 있다.matrix 보다 효과 가 좋 을 것 이 라 고 말 하지만 효과 가 어떤 지 는 확실히 평가 할 수 없다.이 속성의 구체 적 인 작용 부터 말 해 봐.우 리 는 실제 수요 에서 이런 상황 을 만 날 수 있 습 니 다.사람의 얼굴 사진 을 표시 할 때 그림 을 가운데 로 표시 합 니 다.예전 에 저도 이런 수 요 를 만난 적 이 있 습 니 다.그러나 그 때 는 matrix 속성 으로 이 루어 졌 습 니 다.서버 는 우리 얼굴의 중심 좌표 위 치 를 전달 한 다음 에 클 라 이언 트 는 사람의 얼굴 중심 위치 에 따라 이미 지 를 평평 하 게 이동 해 야 합 니 다.그림 을 크기 조정 해 야 합 니 다.matrix 를 사용 하려 면 matrix.postscale()과 matrix.postTranslate()두 가지 방법 으로 이 루어 져 야 합 니 다.당시 의 처리 방식 을 간단히 붙이다.
@Override
public void onLoadingComplete(String s, View view, Bitmap bitmap) {
float bitmapWidth = bitmap.getWidth();
float bitmapHeight = bitmap.getHeight();
Scale[o] = (params[o].height / bitmapHeight >= params[o].width / bitmapWidth) ? params[o].height / bitmapHeight : params[o].width / bitmapWidth;
float scaleBitmapWidth = Scale[o] * bitmapWidth;
float scaleBitmapHeight = Scale[o] * bitmapHeight;
Matrix matrix = new Matrix();
matrix.postScale(Scale[o], Scale[o]);
if (scaleBitmapWidth > scaleBitmapHeight) { //
if (imagedata.get(o).getFace_center_x() == 0 && imagedata.get(o).getFace_center_y() == 0) {
if(scaleBitmapWidth - params[o].width < 0.5 * scaleBitmapWidth - params[o].width / 2){
matrix.postTranslate( params[o].width - scaleBitmapWidth ,0);
}else{
matrix.postTranslate(-(0.5f * scaleBitmapWidth - params[o].width / 2), 0);
}
} else {
if(scaleBitmapWidth - params[o].width < scaleBitmapWidth * imagedata.get(o).getFace_center_x() - params[o].width / 2) {
matrix.postTranslate(params[o].width - scaleBitmapWidth, 0);
} else {
if (scaleBitmapWidth * imagedata.get(o).getFace_center_x() - params[o].width / 2 < 0) {
matrix.postTranslate(0, 0);
} else {
matrix.postTranslate(-(scaleBitmapWidth * imagedata.get(o).getFace_center_x() - params[o].width / 2), 0);
}
}
}
} else { //
if (imagedata.get(o).getFace_center_x() == 0 && imagedata.get(o).getFace_center_y() == 0) {
if(scaleBitmapHeight - params[o].height < 0.5 * scaleBitmapHeight - params[o].height / 2){
matrix.postTranslate(0, params[o].height - scaleBitmapHeight);
}else{
matrix.postTranslate(0,-(0.5f * scaleBitmapHeight - params[o].height / 2));
}
} else {
if (scaleBitmapHeight - params[o].height < scaleBitmapHeight * imagedata.get(o).getFace_center_y() - params[o].height / 2) {
matrix.postTranslate(0, params[o].height - scaleBitmapHeight);
} else {
if (scaleBitmapHeight * imagedata.get(o).getFace_center_y() - params[o].height / 2 < 0) {
matrix.postTranslate(0, 0);
} else {
matrix.postTranslate(0, -(scaleBitmapHeight * imagedata.get(o).getFace_center_y() - params[o].height / 2));
}
}
}
}
vh.image[o].setImageMatrix(matrix);
}
이 형식 은 정말 아프다.이것 이 바로 그 당시 에 우리 의 실제 프로젝트 수 요 였 다.그 당시 에 GridView 였 는데 그 중 한 줄 에 세 장의 그림 이 있 었 다.세 장의 그림 을 동시에 제어 해 야 했다.만약 에 사람 사진 이 라면 두상 을 중앙 으로 옮 겨 야 했다.만약 에 사람 사진 이 아니라면 중앙 위 치 를 표시 하면 된다.그 당시 에 실현 한 것 은 매우 번 거 로 웠 다.너비 그림 과 높이 그림 을 판단 하 였 습 니 다.그림 은 너비 그림 과 높이 그림 으로 나 뉘 기 때문에 크기 조정 비율 을 계산 할 때 이들 에 대한 판단 이 필요 합 니 다.크기 조정 비율의 계산=실제 표 시 된 사이즈/그림 의 실제 크기 는 그림 에 따라 크기 조정 비율 을 설정 해 야 합 니 다.과도 한 크기 조정 문제 가 발생 하지 않 으 며,동시에 평평 하 게 이동 하 는 사 이 즈 는 과도 해 서 는 안 된다.예 를 들 어 우리 ImageView 의 실제 디 스 플레이 폭 은 100 입 니 다.우 리 는 그림 을 크기 조정 했 습 니 다.크기 를 조정 한 후에 그림 의 폭 은 110 입 니 다.그러면 우리 가 이동 할 수 있 는 최대 거 리 는 10 개의 단위 입 니 다.10 개의 단 위 를 초과 해 서 는 안 됩 니 다.그렇지 않 으 면 표시 할 때 문제 가 발생 할 수 있 습 니 다.그리고 우 리 는 그림 을 가능 한 한 가운데 로 표시 해 야 한다.즉,가능 한 한 그림 을 손실 시 키 는 단 위 를 작 게 해 야 한다.그러면 우 리 는 그림 을 5 개 단위 로 옮 길 수 밖 에 없다.즉,좌우 양쪽 에 각각 5 개 단 위 를 손실 하 는 것 이다.이런 표 시 는 완전히 한쪽 으로 치 우 쳐 10 개 단 위 를 손실 하 는 것 보다 훨씬 좋다.여기 서 볼 수 있 듯 이 matrix 를 사용 하 는 것 은 매우 복잡 하 다.또한 이곳 의 코드 는 최적화 할 수 있 지만 최적화 가 끝 난 후에 도 사실은 비교적 번거롭다.
만약 우리 가 Fresco 의 focusCrop 속성 을 사용한다 면 일 은 매우 간단 해 질 것 이다.
fresco:actualImageScaleType="focusCrop"
xml 에서 크기 조정 형식 을 focusCrop 으로 설정 한 다음 자바 코드 에 설정 합 니 다.
PointF focusPoint;
// your app populates the focus point
mSimpleDraweeView
.getHierarchy()
.setActualImageFocusPoint(focusPoint);
여기 서 focusPoint 는 바로 우리 중심 점 의 상대 적 인 위치 입 니 다.float 유형,(0.5,0.5)은 centerCrop 중앙 위치 에 해당 합 니 다.(1.0,1.0)즉 그림 의 맨 아래 에 있 는 위치 입 니 다.그러면 사람 사진 을 표시 할 때 문제 가 매우 가 볍 고 이미지 중심 에 있 는 상대 적 인 위치 만 전달 하면 프레스 코 는 자동 으로 좌표 점 을 중심 으로 표 시 됩 니 다.보아하니 꽤 간단 한 것 같다.가끔 은 기 존의 Scale Type 이 당신 의 요구 에 부합 되 지 않 을 때 가 있 습 니 다.저 희 는 Scaling Utils.Scale Type 을 실현 하여 확장 할 수 있 습 니 다.이 인터페이스 에는 하나의 방법 만 있 습 니 다.getTransform 은 다음 과 같은 매개 변 수 를 바탕 으로 행렬 을 계산 하고 공식 적 으로 제 시 된 예 를 간단하게 설명 합 니 다.
공식 적 인 예 는 바로 이 렇 습 니 다.실제 View 에 사 이 즈 를 표시 한 다음 에 그림 의 디 스 플레이 사 이 즈 를 주 었 습 니 다.만약 에 그림 을 직접 깔 면 그림 이 완전 하 게 표 시 될 수 있 지만 픽 셀 점 이 손실 되 었 습 니 다.그러면 이 때 는 너비 의 줄 크기 를 400 으로 조정 해 야 합 니 다.그러면 이때 가로 로 화면 에 완전히 표시 할 수 있 습 니 다.그러나 높이 는 낮 아 졌 고 그림 은 210 에서 200 으로 바 뀌 었 으 나 실제 표 시 된 높이 는 300 이다.이때 fitCenter 를 사용 하여 너비 와 높이 를 유지 하고 축소 하거나 확대 하여 그림 을 표시 경계 에 완전히 표시 하고 너비 나 높이 가 일치 하 게 경 계 를 표시 한다.가운데 보이 기.전체적으로 차이 가 많 지 않다 는 것 이 바로 이 뜻 이다.그러나 자신 은 의미 가 없다 고 느 꼈 다.높이 는 확실히 축소 되 었 지만 너비 도 축소 되 었 다.그러면 너 비 는 픽 셀 을 잃 게 될 것 이다.확 대 된 픽 셀 에 불과 합 니 다.
여기 가 바로 공식 적 으로 제시 한 예 입 니 다.여기 서 min 이 표시 하 는 것 이 가장 작 아야 합 니 다.공식 번역 은 가장 큰 것 입 니 다.아래 의 방법 을 구체 적 으로 연구 하지 않 았 기 때문에 느낌 과 matrix 를 사용 하 는 것 은 차이 가 많 지 않 지만 확실히 많이 간소화 되 었 다.
public static abstract class AbstractScaleType implements ScaleType {
@Override
public Matrix getTransform(Matrix outTransform, Rect parentRect, int childWidth, int childHeight, float focusX, float focusY) {
//
final float sX = (float) parentRect.width() / (float) childWidth;
final float sY = (float) parentRect.height() / (float) childHeight;
float scale = Math.min(scaleX, scaleY);
// , x、y
float dx = parentRect.left + (parentRect.width() - childWidth * scale) * 0.5f;
float dy = parentRect.top + (parentRect.height() - childHeight * scale) * 0.5f;
//
outTransform.setScale(scale, scale);
outTransform.postTranslate((int) (dx + 0.5f), (int) (dy + 0.5f));
return outTransform;
}
}
3.ControllerBuilder,ControllerListener,PostProcesser,Image RequestController Builder 는 Controller 를 구축 하 는 데 사 용 됩 니 다.지난번 에 Controller 를 간단하게 소 개 했 습 니 다.주로 컨트롤 러,그림 의 uri 를 설정 하고 다시 불 러 올 수 있 는 지 등 이 있 습 니 다.그러면 Controller Builder 는 build 모드 로 Controller 를 구축 하 는 것 입 니 다.
Controller Listener 는 다운로드 한 감청 사건 을 제어 하 는 데 사 용 됩 니 다.그림 다운로드 가 완료 되 거나 그 후에 모든 속성 을 설정 해 야 한다 면 Controller Listener 는 이 기능 을 실현 하 는 데 도움 을 줄 수 있 습 니 다.그러나 이 감청 사건 에 서 는 그림 을 수정 할 수 없습니다.그림 을 수정 해 야 한다 면 PostProcesser 프로세서 로 그림 을 수정 해 야 합 니 다.ImageRequest 는 더 많은 속성 을 설정 하 는 데 사 용 됩 니 다.관련 uri 를 설정 할 수도 있 습 니 다.점진 적 로 딩 을 지원 하 는 지,또는 사후 처리 장 치 를 설정 할 수도 있 습 니 다.이 몇 가 지 는 필연 적 인 관계 가 있 음 을 알 수 있 기 때문에 이 세 가지 기능 을 함께 놓 고 소개 한다.
여기 서 gif 그림 에 Controller Listener 를 설정 하 였 습 니 다.그림 이 성공 하고 그림 에 애니메이션 효과 가 존재 한다 면 애니메이션 효 과 를 재생 합 니 다.그렇지 않 으 면 toast 메 시 지 를 재생 합 니 다.
ControllerListener controllerListener = new BaseControllerListener(){
@Override
public void onFinalImageSet(String id, Object imageInfo, Animatable animatable) {
if(animatable!=null){
animatable.start();
}
}
@Override
public void onFailure(String id, Throwable throwable) {
Toast.makeText(context," ",Toast.LENGTH_SHORT).show();
}
};
DraweeController gifController = Fresco.newDraweeControllerBuilder()
.setUri(Uri.parse("http://img.huofar.com/data/jiankangrenwu/shizi.gif"))
.setOldController(gifImageView.getController())
.setControllerListener(controllerListener)
.build();
gifImageView.setController(gifController);
이해 하기 가 쉬 워 요.그럼 여기 서 다시 사용 한 후 처리 장 치 를 간단하게 처리 하 겠 습 니 다.
Postprocessor redMeshPostProcessor = new BasePostprocessor() {
@Override
public void process(Bitmap bitmap) {
for (int x = 0; x < bitmap.getWidth(); x+=2) {
for (int y = 0; y < bitmap.getHeight(); y+=2) {
bitmap.setPixel(x, y, Color.TRANSPARENT);
}
}
}
@Override
public String getName() {
return super.getName();
}
};
ImageRequest processorImageRequest = ImageRequestBuilder
.newBuilderWithSource(Uri.parse("http://avatar.csdn.net/4/E/8/1_y1scp.jpg"))
.setPostprocessor(redMeshPostProcessor)
.build();
DraweeController processorController = Fresco.newDraweeControllerBuilder()
.setImageRequest(processorImageRequest)
.setOldController(processImageView.getController())
.build();
processImageView.setController(processorController);
그림 에 작은 원점 을 그 렸 습 니 다.이 속성 설정 은 ImageRequest 를 사용 하여 설정 후 프로세서 가 필요 합 니 다.ImageRequest 의 최저 요청 단계
1.메모리 캐 시 를 검사 합 니 다.예 를 들 어 즉시 되 돌려 줍 니 다.이 조작 은 실시 간 이다.
2.디 코딩 되 지 않 은 그림 캐 시 를 확인 하고 있 으 면 디 코딩 하고 되 돌려 줍 니 다.
3.디스크 캐 시 를 확인 하고 로 딩,디 코딩 이 있 으 면 되 돌려 줍 니 다.
4.로 컬 파일 을 다운로드 하거나 불 러 옵 니 다.크기 와 회전 을 조정 하고 디 코딩 을 하고 되 돌려 줍 니 다.네트워크 그림 에 있어 서 이 절 차 는 내 려 오 는 데 가장 시간 이 걸린다.
setLowest Permitted RequestLevel 은 최소 요청 단 계 를 설정 할 수 있 습 니 다.요청 단 계 는 위 와 대응 하 는 몇 가지 값 이 있 습 니 다.
4.점진 적 JPEG 설정,움 직 이 는 그림 표시.
점진 적 JPEG 는 우리 가 그림 을 불 러 올 때 네트워크 가 느 리 면 그림 이 모호 함 에서 선명 함 으로 점점 나타 나 는 것 을 점진 적 JPEG 라 고 한다.구체 적 인 사용 은 다음 과 같다.
/**
* JPEG Config
* */
ProgressiveJpegConfig config = new ProgressiveJpegConfig() {
@Override
public int getNextScanNumberToDecode(int scanNumber) {
return 0;
}
@Override
public QualityInfo getQualityInfo(int scanNumber) {
return null;
}
};
/**
* ImagePipeline Config
* */
ImagePipelineConfig imagePipelineConfig = ImagePipelineConfig.newBuilder(context)
.setProgressiveJpegConfig(config)
.setDownsampleEnabled(true)
.build();
/**
* Fresco JPEG
* */
Fresco.initialize(this,imagePipelineConfig);
초기 화 할 때 이 설정 을 해 야 합 니 다.그렇지 않 으 면 점진 적 인 JPEG 가 나타 나 지 않 습 니 다.
ImageRequest request = ImageRequestBuilder.newBuilderWithSource(Uri.parse("http://pooyak.com/p/progjpeg/jpegload.cgi"))
.setProgressiveRenderingEnabled(true) // JPEG
.build();
DraweeController progressiveJPEGController = Fresco.newDraweeControllerBuilder()
.setImageRequest(request)
.setOldController(progressiveJpegImageView.getController())
.build();
progressiveJpegImageView.setController(progressiveJPEGController);
움 직 이 는 그림 은 사실 할 말 이 없 으 며,Controller 도 너무 많은 설정 을 할 필요 가 없다.
DraweeController gifController = Fresco.newDraweeControllerBuilder()
.setUri(Uri.parse("http://img.huofar.com/data/jiankangrenwu/shizi.gif"))
.setAutoPlayAnimations(true) //
.setOldController(gifImageView.getController())
.build();
gifImageView.setController(gifController);
setAutoPlayAnimations()를 true 로 설정 하면 불 러 온 후에 자동 으로 재생 할 수 있 습 니 다.수 동 으로 제어 하려 면 Controller Listener 로 제어 하거나 contrller 로 animations 에 직접 접근 하면 됩 니 다.
Animatable animatable = mSimpleDraweeView.getController().getAnimatable();
if (animatable != null) {
animatable.start();
// later
animatable.stop();
}
메모:그림 을 높 은 버 전의 Fresco 에 설정 하려 면 gradle 을 도입 하여 애니메이션 속성 을 지원 해 야 합 니 다.compile 'com.facebook.fresco:animated-gif:0.14.0'
마지막 으로 데모:데모 다운로드를 놓 습 니 다.
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Kotlin의 기초 - 2부지난 글에서는 Kotlin이 무엇인지, Kotlin의 특징, Kotlin에서 변수 및 데이터 유형을 선언하는 방법과 같은 Kotlin의 기본 개념에 대해 배웠습니다. 유형 변환은 데이터 변수의 한 유형을 다른 데이터...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.