iOS에서 그림의 압축 해제에 대해 이야기하다

2763 단어
그림 불러오는 작업 흐름
요약하자면 디스크에서 그림을 로드하고 화면에 표시하는 주요 워크플로우는 다음과 같습니다.
  • 만약에 우리가 +imageWithContents Offile를 사용한다면 방법은 디스크에서 그림을 한 장 불러오는데 이때 그림이 압축을 풀지 않았다.
  • 다음에 생성된 UIImage를 UIImageView에 부여하기;
  • 이어서 은밀한 CATransaction이 UIImageView 도층 트리의 변화를 포착했다.
  • 메인 라인의 다음run loop이 도착했을 때Core Animation은 이 은식transaction을 제출했다. 이 과정은 그림에 대해copy작업을 할 수 있고 그림의 바이트 정렬 여부 등 요소의 영향을 받을 수 있다. 이copy작업은 다음과 같은 부분이나 모든 절차와 관련될 수 있다. a. 메모리 버퍼를 분배하여 파일의 IO와 압축 해제 작업을 관리하는 데 사용한다.b. 파일 데이터를 디스크에서 메모리로 읽습니다.c. 압축된 이미지 데이터를 압축되지 않은 비트맵 형식으로 디코딩하는데 이것은 매우 많은 시간을 소모하는 CPU 조작이다.d. 마지막으로 Core Animation은 압축되지 않은 비트맵 데이터를 사용하여 UIImageView의 레이어를 렌더링합니다.

  • 위에서 언급한 바와 같이 그림의 압축 해제는 매우 많은 시간을 소모하는 CPU 작업이며 기본적으로 주 라인에서 실행된다.그러면 불러올 그림이 비교적 많을 때 우리 응용의 응답성에 심각한 영향을 미칠 수 있다. 특히 빠르게 미끄러지는 목록에서 이 문제는 더욱 두드러진다.
    왜 압축을 풀어야 합니까
    그림의 압축 해제는 대량의 CPU 시간을 소모해야 하는 이상 우리는 왜 그림에 대해 압축 해제를 해야 합니까?압축을 풀지 않고 그림을 화면에 직접 표시할 수 있습니까?답안은 부정적이다.이 문제를 이해하려면 먼저 비트맵이 무엇인지 알아야 합니다.
    A bitmap image (or sampled image) is an array of pixels (or samples). Each pixel represents a single point in the image. JPEG, TIFF, and PNG graphics files are examples of bitmap images.
    사실 비트맵은 하나의 픽셀 수조로 수조의 모든 픽셀은 그림의 한 점을 대표한다.우리가 응용 프로그램에서 자주 사용하는 JPEG와 PNG 그림이 바로 비트맵이다.다음은 PNG 이미지로 픽셀이 30 인 구체적인 예를 살펴보겠습니다.×파일 크기 843B
    다음 코드를 사용합니다.
    UIImage *image = [UIImage imageNamed:@"check_green"];
    CFDataRef rawData = CGDataProviderCopyData(CGImageGetDataProvider(image.CGImage));
    

    그림% 1개의 캡션을 편집했습니다.
    사실 JPEG든 PNG 그림이든 모두 압축된 비트맵 도형 형식이다.다만 PNG 이미지는 무손실 압축이고 알파 채널을 지원하며 JPEG 이미지는 손실 압축으로 0-100%의 압축비를 지정할 수 있다.특히 애플의 SDK에서는 PNG와 JPEG 이미지를 생성하는 데 사용되는 두 가지 함수를 제공합니다.
    // return image as PNG. May return nil if image has no CGImageRef or invalid bitmap format
    UIKIT_EXTERN NSData * __nullable UIImagePNGRepresentation(UIImage * __nonnull image);
    
    // return image as JPEG. May return nil if image has no CGImageRef or invalid bitmap format. compression is 0(most)..1(least)                           
    UIKIT_EXTERN NSData * __nullable UIImageJPEGRepresentation(UIImage * __nonnull image, CGFloat compressionQuality);
    
    

    따라서 디스크에 있는 그림을 화면에 렌더링하기 전에 반드시 그림의 원시 픽셀 데이터를 얻어야만 후속적인 그리기 작업을 수행할 수 있다. 이것이 바로 그림에 대한 압축을 풀어야 하는 이유이다.
    강제 압축 해제의 원리
    그림의 압축 해제는 불가피한 것이기 때문에, 우리도 그림이 주 라인에서 실행되고, 우리 응용의 응답성에 영향을 주고 싶지 않다. 그러면 비교적 좋은 해결 방안이 있을까?답은 긍정적이다.
    앞에서 언급한 바와 같이 압축을 풀지 않은 그림이 화면에 렌더링될 때 시스템은 메인 라인에서 그림을 압축을 풀고, 만약 그림이 압축을 풀었다면 시스템은 다시는 그림을 압축을 풀지 않을 것이다.따라서 업계의 해결 방안도 생겨서 서브라인에서 미리 그림에 대한 강제 압축을 풀 수 있다.
    강제 압축 해제의 원리는 그림을 다시 그려서 새로운 압축 해제 후의 비트맵을 얻는 것이다.여기서 가장 핵심적인 함수는 CGBitmapContextCreate입니다.
    전재:http://blog.leichunfeng.com/blog/2017/02/20/talking-about-the-decompression-of-the-image-in-ios/

    좋은 웹페이지 즐겨찾기