UIImageView에서 이미지에 맞는 가로 세로 맞춤을 적용한 후 이미지 크기를 확인하는 방법
'Asect Fit' 모드의 이미지 보기에 이미지를 로드하고 있습니다.이미지 크기를 조정할 크기를 알아야 합니다.제발 도와주세요.
OS 함수 AVMakeRectWithAspectRatioInsideRect를 사용하는 것은 어떻습니까?
사용하고 싶었습니다.AVMakeRectWithAspectRatioInsideRect()
AV Foundation 프레임워크를 포함하지 않습니다.
그래서 저는 다음과 같은 두 가지 유틸리티 기능을 구현했습니다.
CGSize CGSizeAspectFit(CGSize aspectRatio, CGSize boundingSize)
{
float mW = boundingSize.width / aspectRatio.width;
float mH = boundingSize.height / aspectRatio.height;
if( mH < mW )
boundingSize.width = boundingSize.height / aspectRatio.height * aspectRatio.width;
else if( mW < mH )
boundingSize.height = boundingSize.width / aspectRatio.width * aspectRatio.height;
return boundingSize;
}
CGSize CGSizeAspectFill(CGSize aspectRatio, CGSize minimumSize)
{
float mW = minimumSize.width / aspectRatio.width;
float mH = minimumSize.height / aspectRatio.height;
if( mH > mW )
minimumSize.width = minimumSize.height / aspectRatio.height * aspectRatio.width;
else if( mW > mH )
minimumSize.height = minimumSize.width / aspectRatio.width * aspectRatio.height;
return minimumSize;
}
편집: 중복된 분할을 제거하여 아래에 최적화되었습니다.
CGSize CGSizeAspectFit(const CGSize aspectRatio, const CGSize boundingSize)
{
CGSize aspectFitSize = CGSizeMake(boundingSize.width, boundingSize.height);
float mW = boundingSize.width / aspectRatio.width;
float mH = boundingSize.height / aspectRatio.height;
if( mH < mW )
aspectFitSize.width = mH * aspectRatio.width;
else if( mW < mH )
aspectFitSize.height = mW * aspectRatio.height;
return aspectFitSize;
}
CGSize CGSizeAspectFill(const CGSize aspectRatio, const CGSize minimumSize)
{
CGSize aspectFillSize = CGSizeMake(minimumSize.width, minimumSize.height);
float mW = minimumSize.width / aspectRatio.width;
float mH = minimumSize.height / aspectRatio.height;
if( mH > mW )
aspectFillSize.width = mH * aspectRatio.width;
else if( mW > mH )
aspectFillSize.height = mW * aspectRatio.height;
return aspectFillSize;
}
편집 종료
지정된 크기(첫 번째 매개 변수)를 사용하고 가로 세로 비율을 유지합니다.그런 다음 가로 세로 비율을 위반하지 않고 주어진 한계(두 번째 매개 변수)를 최대한 채웁니다.
이를 사용하여 원래 질문에 답합니다.
// Using aspect fit, scale the image (size) to the image view's size.
CGSize sizeBeingScaledTo = CGSizeAspectFit(theImage.size, theImageView.frame.size);
이미지는 가로 세로 비율을 결정하고 이미지 보기는 채울 크기를 결정합니다.
피드백은 매우 환영합니다.
이 답변 대신 @Paul-de-Lange의 답변을 보십시오.
쉽게 액세스할 수 있는 변수에서 이러한 변수가 있는 것을 찾을 수 없었습니다. 따라서 다음과 같은 강력한 방법이 있습니다.
- (CGSize) aspectScaledImageSizeForImageView:(UIImageView *)iv image:(UIImage *)im {
float x,y;
float a,b;
x = iv.frame.size.width;
y = iv.frame.size.height;
a = im.size.width;
b = im.size.height;
if ( x == a && y == b ) { // image fits exactly, no scaling required
// return iv.frame.size;
}
else if ( x > a && y > b ) { // image fits completely within the imageview frame
if ( x-a > y-b ) { // image height is limiting factor, scale by height
a = y/b * a;
b = y;
} else {
b = x/a * b; // image width is limiting factor, scale by width
a = x;
}
}
else if ( x < a && y < b ) { // image is wider and taller than image view
if ( a - x > b - y ) { // height is limiting factor, scale by height
a = y/b * a;
b = y;
} else { // width is limiting factor, scale by width
b = x/a * b;
a = x;
}
}
else if ( x < a && y > b ) { // image is wider than view, scale by width
b = x/a * b;
a = x;
}
else if ( x > a && y < b ) { // image is taller than view, scale by height
a = y/b * a;
b = y;
}
else if ( x == a ) {
a = y/b * a;
b = y;
} else if ( y == b ) {
b = x/a * b;
a = x;
}
return CGSizeMake(a,b);
}
이 간단한 함수는 가로 맞춤 후 영상의 크기를 계산합니다.
스위프트 5.1
extension UIImageView {
var imageSizeAfterAspectFit: CGSize {
var newWidth: CGFloat
var newHeight: CGFloat
guard let image = image else { return frame.size }
if image.size.height >= image.size.width {
newHeight = frame.size.height
newWidth = ((image.size.width / (image.size.height)) * newHeight)
if CGFloat(newWidth) > (frame.size.width) {
let diff = (frame.size.width) - newWidth
newHeight = newHeight + CGFloat(diff) / newHeight * newHeight
newWidth = frame.size.width
}
} else {
newWidth = frame.size.width
newHeight = (image.size.height / image.size.width) * newWidth
if newHeight > frame.size.height {
let diff = Float((frame.size.height) - newHeight)
newWidth = newWidth + CGFloat(diff) / newWidth * newWidth
newHeight = frame.size.height
}
}
return .init(width: newWidth, height: newHeight)
}
}
목표 C:
-(CGSize)imageSizeAfterAspectFit:(UIImageView*)imgview{
float newwidth;
float newheight;
UIImage *image=imgview.image;
if (image.size.height>=image.size.width){
newheight=imgview.frame.size.height;
newwidth=(image.size.width/image.size.height)*newheight;
if(newwidth>imgview.frame.size.width){
float diff=imgview.frame.size.width-newwidth;
newheight=newheight+diff/newheight*newheight;
newwidth=imgview.frame.size.width;
}
}
else{
newwidth=imgview.frame.size.width;
newheight=(image.size.height/image.size.width)*newwidth;
if(newheight>imgview.frame.size.height){
float diff=imgview.frame.size.height-newheight;
newwidth=newwidth+diff/newwidth*newwidth;
newheight=imgview.frame.size.height;
}
}
NSLog(@"image after aspect fit: width=%f height=%f",newwidth,newheight);
//adapt UIImageView size to image size
//imgview.frame=CGRectMake(imgview.frame.origin.x+(imgview.frame.size.width-newwidth)/2,imgview.frame.origin.y+(imgview.frame.size.height-newheight)/2,newwidth,newheight);
return CGSizeMake(newwidth, newheight);
}
스위프트 3 인간이 읽을 수 있는 버전
extension UIImageView {
/// Find the size of the image, once the parent imageView has been given a contentMode of .scaleAspectFit
/// Querying the image.size returns the non-scaled size. This helper property is needed for accurate results.
var aspectFitSize: CGSize {
guard let image = image else { return CGSize.zero }
var aspectFitSize = CGSize(width: frame.size.width, height: frame.size.height)
let newWidth: CGFloat = frame.size.width / image.size.width
let newHeight: CGFloat = frame.size.height / image.size.height
if newHeight < newWidth {
aspectFitSize.width = newHeight * image.size.width
} else if newWidth < newHeight {
aspectFitSize.height = newWidth * image.size.height
}
return aspectFitSize
}
/// Find the size of the image, once the parent imageView has been given a contentMode of .scaleAspectFill
/// Querying the image.size returns the non-scaled, vastly too large size. This helper property is needed for accurate results.
var aspectFillSize: CGSize {
guard let image = image else { return CGSize.zero }
var aspectFillSize = CGSize(width: frame.size.width, height: frame.size.height)
let newWidth: CGFloat = frame.size.width / image.size.width
let newHeight: CGFloat = frame.size.height / image.size.height
if newHeight > newWidth {
aspectFillSize.width = newHeight * image.size.width
} else if newWidth > newHeight {
aspectFillSize.height = newWidth * image.size.height
}
return aspectFillSize
}
}
또한 가로 세로 비율을 적용하여 테이블 뷰의 셀 높이를 계산할 수 있도록 한 후 높이를 계산하고 싶었습니다.그래서 작은 수학을 통해 성취했습니다.
ratio = width / height
그리고 키가 될 것입니다.
height = width / ratio
그래서 코드 스니펫은
UIImage *img = [UIImage imageNamed:@"anImage"];
float aspectRatio = img.size.width/img.size.height;
float requiredHeight = self.view.bounds.size.width / aspectRatio;
Swift의 경우 아래 코드를 사용합니다.
func imageSizeAspectFit(imgview: UIImageView) -> CGSize {
var newwidth: CGFloat
var newheight: CGFloat
let image: UIImage = imgFeed.image!
if image.size.height >= image.size.width {
newheight = imgview.frame.size.height;
newwidth = (image.size.width / image.size.height) * newheight
if newwidth > imgview.frame.size.width {
let diff: CGFloat = imgview.frame.size.width - newwidth
newheight = newheight + diff / newheight * newheight
newwidth = imgview.frame.size.width
}
}
else {
newwidth = imgview.frame.size.width
newheight = (image.size.height / image.size.width) * newwidth
if newheight > imgview.frame.size.height {
let diff: CGFloat = imgview.frame.size.height - newheight
newwidth = newwidth + diff / newwidth * newwidth
newheight = imgview.frame.size.height
}
}
print(newwidth, newheight)
//adapt UIImageView size to image size
return CGSizeMake(newwidth, newheight)
}
및 통화 기능
imgFeed.sd_setImageWithURL(NSURL(string:"Your image URL")))
self.imageSizeAfterAspectFit(imgFeed)
귀하의 경우에 맞지 않을 수도 있지만, 이 간단한 접근 방식은 유사한 경우에 제 문제를 해결합니다.
UIImageView *imageView = [[UIImageView alloc] initWithImage:bigSizeImage];
[imageView sizeToFit];
imageView.frame.size를 쿼리하면 sizeToFit이 실행된 후 새 이미지 크기에 맞는 새 이미지 보기 크기가 표시됩니다.
Swift 4: 프레임:.aspectFit
이미지는 -입니다.
import AVFoundation
let x: CGRect = AVMakeRect(aspectRatio: myImage.size, insideRect: sampleImageView.frame)
+(UIImage *)CreateAResizeImage:(UIImage *)Img ThumbSize:(CGSize)ThumbSize
{
float actualHeight = Img.size.height;
float actualWidth = Img.size.width;
if(actualWidth==actualHeight)
{
actualWidth = ThumbSize.width;
actualHeight = ThumbSize.height;
}
float imgRatio = actualWidth/actualHeight;
float maxRatio = ThumbSize.width/ThumbSize.height; //320.0/480.0;
if(imgRatio!=maxRatio)
{
if(imgRatio < maxRatio)
{
imgRatio = ThumbSize.height / actualHeight; //480.0 / actualHeight;
actualWidth = imgRatio * actualWidth;
actualHeight = ThumbSize.height; //480.0;
}
else
{
imgRatio = ThumbSize.width / actualWidth; //320.0 / actualWidth;
actualHeight = imgRatio * actualHeight;
actualWidth = ThumbSize.width; //320.0;
}
}
else
{
actualWidth = ThumbSize.width;
actualHeight = ThumbSize.height;
}
CGRect rect = CGRectMake(0, 0, (int)actualWidth, (int)actualHeight);
UIGraphicsBeginImageContext(rect.size);
[Img drawInRect:rect];
UIImage *NewImg = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return NewImg;
}
Swift 3 UIImageView 확장자:
import AVFoundation
extension UIImageView {
var imageSize: CGSize {
if let image = image {
return AVMakeRect(aspectRatio: image.size, insideRect: bounds).size
}
return CGSize.zero
}
}
이 한 줄로 이 작업을 수행할 수 있습니다.
CGSize sizeInView = AVMakeRectWithAspectRatioInsideRect(imgViewFake.image.size, imgViewFake.bounds).size;
허용된 답변은 매우 복잡하며 일부 에지 사례에서는 실패합니다.저는 이 솔루션이 훨씬 더 우아하다고 생각합니다.
- (CGSize) sizeOfImage:(UIImage*)image inAspectFitImageView:(UIImageView*)imageView
{
UKAssert(imageView.contentMode == UIViewContentModeScaleAspectFit, @"Image View must use contentMode = UIViewContentModeScaleAspectFit");
CGFloat imageViewWidth = imageView.bounds.size.width;
CGFloat imageViewHeight = imageView.bounds.size.height;
CGFloat imageWidth = image.size.width;
CGFloat imageHeight = image.size.height;
CGFloat scaleFactor = MIN(imageViewWidth / imageWidth, imageViewHeight / imageHeight);
return CGSizeMake(image.size.width*scaleFactor, image.size.height*scaleFactor);
}
다음은 동일한 문제에 대한 저의 해결책입니다: https://github.com/alexgarbarev/UIImageView-ImageFrame
장점:
- 지원되는 UIViewContentMode 모드
- 스케일과 rect를 별도로 쿼리할 수 있습니다.
- UIImageView에서 이미지 프레임에 대해 바로 물어볼 수 있습니다.
AV Foundation이 필요 없는 솔루션입니다.
먼저 다른 크기에 맞는 크기를 계산하기 위한 CG 크기 확장입니다.
extension CGSize
{
func sizeThatFitsSize(_ aSize: CGSize) -> CGSize
{
let width = min(self.width * aSize.height / self.height, aSize.width)
return CGSize(width: width, height: self.height * width / self.width)
}
}
따라서 OP의 문제에 대한 해결책은 다음과 같습니다.
let resultSize = image.size.sizeThatFitsSize(imageView.bounds.size)
또한 다음은 다른 정류 내에 정류를 장착하기 위한 또 다른 확장입니다(위의 CG 크기 확장을 사용합니다).
extension CGRect
{
func rectThatFitsRect(_ aRect:CGRect) -> CGRect
{
let sizeThatFits = self.size.sizeThatFitsSize(aRect.size)
let xPos = (aRect.size.width - sizeThatFits.width) / 2
let yPos = (aRect.size.height - sizeThatFits.height) / 2
let ret = CGRect(x: xPos, y: yPos, width: sizeThatFits.width, height: sizeThatFits.height)
return ret
}
}
스위프트 5 확장
extension CGSize {
func aspectFit(to size: CGSize) -> CGSize {
let mW = size.width / self.width;
let mH = size.height / self.height;
var result = size
if( mH < mW ) {
result.width = size.height / self.height * self.width;
}
else if( mW < mH ) {
result.height = size.width / self.width * self.height;
}
return result;
}
func aspectFill(to size: CGSize) -> CGSize {
let mW = size.width / self.width;
let mH = size.height / self.height;
var result = size
if( mH > mW ) {
result.width = size.height / self.height * self.width;
}
else if( mW > mH ) {
result.height = size.width / self.width * self.height;
}
return result;
}
}
Swift에서 다음을 사용하고 있습니다.
private func CGSizeAspectFit(aspectRatio:CGSize,boundingSize:CGSize) -> CGSize
{
var aspectFitSize = boundingSize
let mW = boundingSize.width / aspectRatio.width
let mH = boundingSize.height / aspectRatio.height
if( mH < mW )
{
aspectFitSize.width = mH * aspectRatio.width
}
else if( mW < mH )
{
aspectFitSize.height = mW * aspectRatio.height
}
return aspectFitSize
}
private func CGSizeAspectFill(aspectRatio:CGSize,minimumSize:CGSize) -> CGSize
{
var aspectFillSize = minimumSize
let mW = minimumSize.width / aspectRatio.width
let mH = minimumSize.height / aspectRatio.height
if( mH > mW )
{
aspectFillSize.width = mH * aspectRatio.width
}
else if( mW > mH )
{
aspectFillSize.height = mW * aspectRatio.height
}
return aspectFillSize
}
다음과 같이 사용합니다.
let aspectSize = contentMode == .ScaleAspectFill ? CGSizeAspectFill(oldSize,minimumSize: newSize) : CGSizeAspectFit(oldSize, boundingSize: newSize)
let newRect = CGRect( x: (newSize.width - aspectSize.width)/2, y: (newSize.height - aspectSize.height)/2, width: aspectSize.width, height: aspectSize.height)
CGContextSetFillColorWithColor(context,IOSXColor.whiteColor().CGColor)
CGContextFillRect(context, CGRect(origin: CGPointZero,size: newSize))
CGContextDrawImage(context, newRect, cgImage)
이미지 보기의 너비만 알고 이미지 높이가 동적인 경우 이미지 위와 아래의 공백을 제거하기 위해 지정된 너비에 따라 이미지 높이를 조정해야 합니다.화면의 표준 너비에 따라 이미지 높이를 조정하려면 여기서 다음 방법을 사용합니다.
-(UIImage*)imageWithImage: (UIImage*) sourceImage scaledToWidth: (float) i_width
{
float oldWidth = sourceImage.size.width;
float scaleFactor = i_width / oldWidth;
float newHeight = sourceImage.size.height * scaleFactor;
float newWidth = oldWidth * scaleFactor;
UIGraphicsBeginImageContext(CGSizeMake(newWidth, newHeight));
[sourceImage drawInRect:CGRectMake(0, 0, newWidth, newHeight)];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
그리고 당신의 핸드폰에서 전화하세요 For Row At.IndexPath: 메서드는 다음과 같습니다.
UIImage *img = [dictImages objectForKey:yourImageKey]; // loaded the image
cell.imgView.image = [self imageWithImage:img scaledToWidth:self.view.frame.size.width];
스위프트 4 버전
extension CGSize {
enum AspectMode {
case fit
case fill
}
enum Orientation {
case portrait
case landscape
}
func aspectCorrectSizeToFit(targetSize: CGSize, aspectMode: AspectMode = .fill) -> CGSize {
switch aspectMode {
case .fill: return aspectFill(targetSize: targetSize)
case .fit: return aspectFit(targetSize: targetSize)
}
}
var orientation: Orientation {
if height >= width { return .portrait }
else { return .landscape }
}
func aspectFit(targetSize: CGSize) -> CGSize {
let wRatio = targetSize.width / width
let hRatio = targetSize.height / height
let scale = min(wRatio, hRatio)
return applying(CGAffineTransform(scaleX: scale, y: scale))
}
func aspectFill(targetSize: CGSize) -> CGSize {
let wRatio = targetSize.width / width
let hRatio = targetSize.height / height
let scale = max(wRatio, hRatio)
return applying(CGAffineTransform(scaleX: scale, y: scale))
}
}
위에서 언급한 방법은 필요한 값을 제공하지 않습니다.가로 세로 맞춤은 동일한 가로 세로 비율을 유지하므로 값을 계산하기 위해 간단한 수학만 필요합니다.
가로 세로 비율 감지
CGFloat imageViewAspectRatio = backgroundImageView.bounds.size.width / backgroundImageView.bounds.size.height;
CGFloat imageAspectRatio = backgroundImageView.image.size.width / backgroundImageView.image.size.height;
CGFloat mulFactor = imageViewAspectRatio/imageAspectRatio;
새 값 가져오기
CGFloat newImageWidth = mulFactor * backgroundImageView.bounds.size.width;
CGFloat newImageHeight = mulFactor * backgroundImageView.bounds.size.height;
언급URL : https://stackoverflow.com/questions/6278876/how-to-know-the-image-size-after-applying-aspect-fit-for-the-image-in-an-uiimage
'programing' 카테고리의 다른 글
ASP 사용 방법.서버 제어 특성의 NET <%= 태그? (0) | 2023.08.04 |
---|---|
TSQL의 열에 대한 기본 제약 조건 삭제 (0) | 2023.07.30 |
코틀린과 새로운 활동테스트 규칙: @Rule은 공개 규칙이어야 합니다. (0) | 2023.07.30 |
주입 및 리소스 및 자동 배선 주석 (0) | 2023.07.30 |
PowerShell의 'forach' 루프에서 해시 테이블 값 업데이트 (0) | 2023.07.30 |