문제

주어진 a uiimage 모든 차원에서 정사각형 "아이콘"크기 버전을 생성하고 싶습니다. px 왜곡없이 픽셀 (스트레칭). 그러나 나는 약간 걸리기입니다. 문제가 어디에 있는지 잘 모르겠습니다. 내가 지금까지하고있는 일은 다음과 같습니다.

먼저, 주어졌습니다 uimage size, 나는 세 가지를 결정합니다 ratio 이미지를 스케일링 할 때 사용합니다. ㅏ delta (원하는 아이콘 크기와 가장 긴면의 차이) offset (이미지를 클리핑 할 때 원산지 좌표를 파악하는 데 사용됩니다) :

 if (size.width > size.height) {
   ratio = px / size.width;
   delta = (ratio*size.width - ratio*size.height);
   offset = CGPointMake(delta/2, 0);
 } else {
   ratio = px / size.height;
   delta = (ratio*size.height - ratio*size.width);
   offset = CGPointMake(0, delta/2);
 }

이제 480px 높이의 640px 이미지를 가지고 있다고 가정 해 봅시다.이 중 50px x 50px 아이콘을 얻고 싶다고 가정 해 봅시다. 너비는 높이보다 크기 때문에 계산은 다음과 같습니다.

ratio = 50px / 640px = 0.078125
delta = (ratio * 640px) - (ratio * 480px) = 50px - 37.5px = 12.5px
offset = {x=6.25, y=0}

다음으로, 나는 a를 만듭니다 cgrect rect 그것은 왜곡없이 원하는 아이콘 크기로 자르기에 충분히 큽니다. clipRect 클리핑 목적 :

CGRect rect = CGRectMake(0.0, 0.0, (ratio * size.width) + delta,
                                   (ratio * size.height) + delta);
CGRect clipRect = CGRectMake(offset.x, offset.y, px, px);

위에서 우리의 가치를 대체하면 다음을 얻을 수 있습니다.

rect = origin {x=0.0, y=0.0}, size {width=62.5, height=50.0}
clipRect = origin {x=6.25, y=0}, size {width=50.0, height=50.0}

이제 우리는 폭이 62.5px x 50px 높이의 직장과 함께 작동하며 "중간"50x50 부분을 잡는 클리핑 사각형이 있습니다.

홈 스트레치에! 다음으로, 우리는 이미지 컨텍스트를 설정하고 uiimage (라고 불리는 myImage 여기) rect로, 클리핑 사각형을 설정하고 (아마도 클리핑 된) 이미지를 가져 와서 사용하고 마지막으로 이미지 컨텍스트를 정리하십시오.

 UIGraphicsBeginImageContext(rect.size);
 [myImage drawInRect:rect]; 
 UIRectClip(clipRect);
 UIImage *icon = UIGraphicsGetImageFromCurrentImageContext();

 // Do something with the icon here ...

 UIGraphicsEndImageContext();

단 하나의 문제 : 클리핑은 결코 일어나지 않습니다! 나는 이미지 63px 너비의 x 50px 높이로 끝납니다. :(

아마도 나는 오용/오해를하고있을 것입니다 uirectClip? 나는 주위에 다양한 것들을 뒤섞려고 시도했다 : rect 그리고 clipRect, 움직입니다 uirectClip ~ 전에 DrawInrect :. 주사위가 없습니다.

이 방법의 예를 온라인으로 검색하려고 시도했습니다. 기록을 위해 uirectClip 다음과 같이 정의됩니다.

지정된 사각형과 교차하여 전류 클리핑 경로를 수정합니다.

주위에 물건을 뒤섞습니다. 조금 더 가까워집니다.

UIGraphicsBeginImageContext(clipRect.size);
UIRectClip(rect);
[myImage drawInRect:rect];

이제는 왜곡이 없지만 잘린 이미지는 예상대로 원본을 중심으로하지 않습니다. 그럼에도 불구하고, 최소한 이미지는 50x50이지만, 변수 이름은 이제 셔플 링의 결과로 파울입니다. (나는 독자를위한 운동으로 바꾸는 것을 정중하게 남겨 둘 것입니다.)

도움이 되었습니까?

해결책

유레카! 나는 조금 섞여 있었다. 이것은 작동합니다 :

CGRect clipRect = CGRectMake(-offset.x, -offset.y,
                             (ratio * size.width) + delta,
                             (ratio * size.height) + delta);
UIGraphicsBeginImageContext(CGSizeMake(px, px));
UIRectClip(clipRect);
[myImage drawInRect:clipRect];
UIImage *icon = UIGraphicsGetImageFromCurrentImageContext();

// Do something with the icon here ...

UIGraphicsEndImageContext();

더 이상 필요하지 않습니다 rect. 트릭은 a를 사용하는 것으로 보입니다 부정적인 클리핑 사각형에서 오프셋하여 50 x 50 이미지 (이 예에서)를 잡으려는 위치의 원점을 정렬합니다.

아마도 더 쉬운 방법이있을 것입니다. 그렇다면 무게를 보내십시오!

다른 팁

나는 비슷한 일을 달성하고 싶었지만 원래 포스터의 답변은 잘 작동하지 않았다. 이미지를 왜곡했습니다. 그는 전체 솔루션을 게시하지 않았고 변수가 초기화되는 방식의 일부를 변경했기 때문에 전적으로 가능할 수 있습니다.

 (if (size.width > size.height) 
       ratio = px / size.width;

내 솔루션에 잘못되었습니다 (소스 이미지에서 가장 큰 사각형을 사용하고 싶었습니다). 또한 UICLIPRECT를 사용할 필요는 없습니다. 컨텍스트를 추출하려는 이미지의 크기를 만들면 실제 도면이 어쨌든 해당 낙타 밖에서 수행되지 않습니다. 그것은 이미지 낙타의 크기를 스케일링하고 원점 좌표 중 하나를 오프셋하는 문제 일뿐입니다. 아래에 내 솔루션을 게시했습니다.

+(UIImage *)makeIconImage:(UIImage *)image
{
    CGFloat destSize = 400.0;
    CGRect rect = CGRectMake(0, 0, destSize, destSize);

    UIGraphicsBeginImageContext(rect.size);

    if(image.size.width != image.size.height)
    {
        CGFloat ratio;
        CGRect destRect;

        if (image.size.width > image.size.height)
        {
            ratio = destSize / image.size.height;

            CGFloat destWidth = image.size.width * ratio;
            CGFloat destX = (destWidth - destSize) / 2.0;

            destRect = CGRectMake(-destX, 0, destWidth, destSize);

        }
        else
        {
            ratio = destSize / image.size.width;

            CGFloat destHeight = image.size.height * ratio;
            CGFloat destY = (destHeight - destSize) / 2.0;

            destRect = CGRectMake(0, destY, destSize, destHeight);
        }
        [image drawInRect:destRect];
    }
    else
    {
        [image drawInRect:rect];
    }
    UIImage *scaledImage = UIGraphicsGetImageFromCurrentImageContext();

    UIGraphicsEndImageContext();

    return scaledImage;
}

Wheeliebin Answer는 맞지만 Desty 앞에서 마이너스 표시를 잊었습니다.

destRect = CGRectMake(0, -destY, destSize, destHeight);
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top