UIIMAGE를 아이콘 크기로 확장하기 위해 UIRECTCLIP의 올바른 사용
문제
주어진 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);