2010-03-29 1 views
1

크기가 2 ~ 4MB 인 이미지로 작업하고 있습니다. 저는 스케일링, 변환 및 회전 작업을 수행하여 해상도 1200x1600의 이미지로 작업하고 있습니다. 그 위에 다른 이미지를 추가하여 사진 앨범에 저장하고 싶습니다. 하나의 이미지를 성공적으로 편집하고 사진에 저장하면 앱이 다운됩니다. 이미지 크기 때문에 일어나는 것 같아요. 이미지의 90 %를 유지하고 싶습니다.크기 2-4Mb의 이미지 (png)로 작업하는 방법

메모리 경고가 표시되면 일부 이미지가 공개됩니다. 그러나 여전히 크기가 3MB 인 2 개의 이미지와 크기 1200x1600의 컨텍스트로 작업하면서 컨텍스트에서 이미지를 동시에 가져올 때 충돌이 발생합니다.

이미지를 압축하고 작업 할 수있는 방법이 있습니까?

+0

잘 알고 있거나 모르지만 잘 모르는 사람들을위한 간단한 메모입니다. 메모리에있는 이미지 크기는 일반적으로 w * h * 4로 계산되므로이 경우 1200 * 1600 * 4 = 7,680,000 (7MB 이상) – Jasarien

+0

메모리 문제인지, 문제가되는 이미지의 크기인지 확인해야합니다. 질문에 확신이 들지 않습니다. 예를 들어 이미지를 500x500으로 사용하는 경우 여전히 이러한 현상이 발생합니까? –

답변

3

나는 의심 스럽다. 아무 것도하지 않고 이미지를 압축하고 압축을 풀어도 정보가 손실됩니다. 나는 압축 된 이미지를 조작하는 알고리즘이 손실이 될 것이라고 생각한다.

기술적으로 가능할 수도 있습니다. 예를 들어 푸리에 변환을 회전하면 원본 이미지가 회전됩니다. 그러나 실제 이미지 압축은 보통 푸리에 변환을 계산하는 것만 큼 간단하지 않습니다.

또는 이미지를 한 입 크기로 잘라서 조각을 변형하고 나중에 다시 어셈블하는 단편적인 알고리즘을 작성할 수 있습니다. 또한 전체 이미지의 더 작은 버전에 동일한 변환을 적용하여 프로세스의 실시간보기를 제공 할 수도 있습니다.

+0

왜 완벽하게 좋은 대답을 downvote? 적어도 의견을 남길 예의를 가져라. – pheelicks

1

키는 이미지 전체 크기로 전체 이미지를 메모리로 완전히 디코딩하지 않습니다.

  1. 이미지를 표시해야 할 경우 전체 크기로 할 이유가 없습니다. iPhone 디스플레이가 너무 작아서 이미지를 표시 할 수 없습니다. 디스플레이 용 이미지 객체의 경우 축소 된 형식으로 이미지를 디코딩합니다.

  2. 처리를 위해 메모리 내 배열 대신 픽셀 스트림에서 작동하는 사용자 지정 코드를 작성해야합니다. 이것이 아이폰에서 이미 사용 가능한지 모르지만 libpng 라이브러리 API에 직접 작성하여 직접 작성할 수 있습니다. 예를 들어

, 당신의 코드는 지금 아마이 (의사 코드) 같은

img = ReadImageFromFile("image.png") 
img2 = RotateImage(img, 90) 
SaveImage(img2, "image2.png") 

이해하는 중요한 건,이 경우, img는 PNG에없는 데이터라는 것이다 보인다 파일 (2MB), 완전히 압축되지 않은 이미지 (~ 6MB). RotateImage (또는 호출 된 것)는이 크기와 비슷한 다른 이미지를 반환합니다. 규모를 확대하면 더 나빠질 것입니다. 이 알고리즘에서

imgPixelGetter = PixelDecoderFromFile("image.png") 
imgPixelSaver = OpenImageForAppending("image2.png") 
w = imgPixelGetter.Width 
h = imgPixelGetter.Height 

// set up a 90 degree rotate 
imgPixelSaver.Width = h 
imgPixelSaver.Height = w 

// read each vertical scanline of pixels 
for (x = 0; x < w; ++x) { 
    pixelRect = imgPixelGetter.ReadRect(x, 0, 1, h) // x, y, w, h 
    pixelRect.Rotate(90); // it's now got a width of h and a height of 1 
    imgPixelSaver.AppendScanLine(pixelRect) 
} 

, 당신이 없었 -

당신은 (당신이 그것을 직접 작성해야 할 수도 있습니다하지만 당신은 그것을 할 수있는 API 년대가되지 않을 수도 있습니다) 다음과 같은 코드를 원하는 전체 이미지를 한 번에 메모리에 저장 - 한 장씩 읽고 그것을 저장했습니다. 크기 조정 및 자르기와 유사한 알고리즘을 작성할 수 있습니다.

메모리에서 이미지를 디코딩하는 것보다 속도가 느려지므로 이미지 형식과 ReadRect()를 수행하는 코드에 따라 다릅니다. 불행히도 PNG는 픽셀에 대한 이러한 종류의 액세스를 위해 설계되지 않았습니다.

관련 문제