【问题标题】:Resizing UIimages pulled from the Camera also ROTATES the UIimage?调整从相机中提取的 UIimages 的大小也会旋转 UIimage?
【发布时间】:2010-11-18 14:47:58
【问题描述】:

我从相机获取 UIimages 并将它们分配给 UIImageViews 以显示。当我这样做时,相机会给我一个 1200 x 1600 像素的图像,然后我将其分配给我的应用程序中的 UIImageView。在这种情况下,图像在图像视图中按预期显示。但是,当我在将检索到的 UIImage 分配给 UIImageView 之前尝试调整它的大小时,图像正在按预期调整大小,但是在某个地方(在调整大小的代码中?)我的 UIImage 正在旋转...结果,当我将调整大小的 UIImage 分配给 UIImageView 时,图像会旋转 90 度并显示为拉伸,因为纵横比(1200 x 1600 像素)没有改变...

我正在使用它从相机中获取 UIImage:

- (void) imagePickerController:(UIImagePickerController*)picker didFinishPickingMediaWithInfo:(NSDictionary*)info
{

        myImg = [info objectForKey:@"UIImagePickerControllerOriginalImage"];
        myResizedImg = [self resizeImage:myImg width:400 height:533];
        [myImageView setImage:myResizedImg];

}

我正在使用它来调整它的大小:

-(UIImage *)resizeImage:(UIImage *)anImage width:(int)width height:(int)height
{

    CGImageRef imageRef = [anImage CGImage];

    CGImageAlphaInfo alphaInfo = CGImageGetAlphaInfo(imageRef);

    if (alphaInfo == kCGImageAlphaNone)
    alphaInfo = kCGImageAlphaNoneSkipLast;


    CGContextRef bitmap = CGBitmapContextCreate(NULL, width, height, CGImageGetBitsPerComponent(imageRef), 4 * width, CGImageGetColorSpace(imageRef), alphaInfo);

    CGContextDrawImage(bitmap, CGRectMake(0, 0, width, height), imageRef);

    CGImageRef ref = CGBitmapContextCreateImage(bitmap);
    UIImage *result = [UIImage imageWithCGImage:ref];

    CGContextRelease(bitmap);
    CGImageRelease(ref);

    return result;  
}

问题:如何在不旋转像素的情况下调整从相机中提取的 UIImage 的大小?

【问题讨论】:

    标签: iphone uiimageview uiimage uiimagepickercontroller


    【解决方案1】:

    您的代码不起作用的原因是您拥有的代码上的 imageOrientation 没有被考虑在内。具体来说,如果 imageOrientation 是右/左,那么您需要旋转图像并交换宽度/高度。这里有一些代码可以做到这一点:

    -(UIImage*)imageByScalingToSize:(CGSize)targetSize
    {
        UIImage* sourceImage = self; 
        CGFloat targetWidth = targetSize.width;
        CGFloat targetHeight = targetSize.height;
    
        CGImageRef imageRef = [sourceImage CGImage];
        CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(imageRef);
        CGColorSpaceRef colorSpaceInfo = CGImageGetColorSpace(imageRef);
    
        if (bitmapInfo == kCGImageAlphaNone) {
            bitmapInfo = kCGImageAlphaNoneSkipLast;
        }
    
        CGContextRef bitmap;
    
        if (sourceImage.imageOrientation == UIImageOrientationUp || sourceImage.imageOrientation == UIImageOrientationDown) {
            bitmap = CGBitmapContextCreate(NULL, targetWidth, targetHeight, CGImageGetBitsPerComponent(imageRef), CGImageGetBytesPerRow(imageRef), colorSpaceInfo, bitmapInfo);
    
        } else {
            bitmap = CGBitmapContextCreate(NULL, targetHeight, targetWidth, CGImageGetBitsPerComponent(imageRef), CGImageGetBytesPerRow(imageRef), colorSpaceInfo, bitmapInfo);
    
        }   
    
        if (sourceImage.imageOrientation == UIImageOrientationLeft) {
            CGContextRotateCTM (bitmap, radians(90));
            CGContextTranslateCTM (bitmap, 0, -targetHeight);
    
        } else if (sourceImage.imageOrientation == UIImageOrientationRight) {
            CGContextRotateCTM (bitmap, radians(-90));
            CGContextTranslateCTM (bitmap, -targetWidth, 0);
    
        } else if (sourceImage.imageOrientation == UIImageOrientationUp) {
            // NOTHING
        } else if (sourceImage.imageOrientation == UIImageOrientationDown) {
            CGContextTranslateCTM (bitmap, targetWidth, targetHeight);
            CGContextRotateCTM (bitmap, radians(-180.));
        }
    
        CGContextDrawImage(bitmap, CGRectMake(0, 0, targetWidth, targetHeight), imageRef);
        CGImageRef ref = CGBitmapContextCreateImage(bitmap);
        UIImage* newImage = [UIImage imageWithCGImage:ref];
    
        CGContextRelease(bitmap);
        CGImageRelease(ref);
    
        return newImage; 
    }
    

    这将调整您的图像大小并将其旋转到正确的方向。如果您需要弧度的定义,则为:

    static inline double radians (double degrees) {return degrees * M_PI/180;}
    

    Daniel 给出的答案也是正确的,但它的问题是它不是线程安全的,因为您使用的是 UIGraphicsBeginImageContext()。由于上面的代码只使用了 CG 函数,所以你已经准备好了。我也有一个类似的功能来调整图像大小和对图像进行适当的方面填充 - 如果这就是你要找的,请告诉我。

    注意:我从 this post 获得了原始函数,并进行了一些修改以使其适用于 JPEG。

    【讨论】:

    • 我如何使用此代码来固定方向,然后旋转到规范。度数?
    • 这段代码似乎对我不起作用;似乎问题在于照片将“向上”方向视为与使用右侧主页按钮拍摄的横向照片相匹配,而此代码将“向上”视为匹配纵向。
    【解决方案2】:

    我也遇到了一些代码的问题,我发现这个代码有效,检查一下,让我知道你发现了什么

    + (UIImage*)imageWithImage:(UIImage*)image 
                   scaledToSize:(CGSize)newSize;
    {
       UIGraphicsBeginImageContext( newSize );
       [image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
       UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
       UIGraphicsEndImageContext();
    
       return newImage;
    }
    

    【讨论】:

    • 此代码不考虑相机方向。它只是将图像缩放到指定的大小。
    • 否,但您可以轻松查询方向并在其中发送适当的尺寸...
    • newImage 的方向总是UIImageOrientationUp 不管image 的方向是什么,但是代码是正确的,因为drawInRect: 考虑了方向并在内部进行了适当的旋转.
    • 这也是我使用的方法。 CGContextDrawImage 调用没有以正确的方向绘制。 drawInRect 调用确实如此。这通过使用已经为其设计的调用来节省所有工作。
    【解决方案3】:

    斯威夫特 3

    我将它添加到 didFinishPickingMediaWithInfo 方法中,然后使用 image 而不用担心它的轮换。

    var image = info[UIImagePickerControllerOriginalImage] as! UIImage
    if (image.imageOrientation != .up) {
      UIGraphicsBeginImageContextWithOptions(image.size, false, image.scale)
      image.draw(in: CGRect(x: 0, y: 0, width: image.size.width, height: image.size.height))
      image = UIGraphicsGetImageFromCurrentImageContext()!
      UIGraphicsEndImageContext()
    }
    

    【讨论】:

      【解决方案4】:

      如果您想通过在两侧按宽度或高度裁剪矩形图像(无论是水平还是垂直)制作方形图像,请使用我的代码。不同之处在于我不拉伸,而是裁剪。我通过修改从顶部代码中制作了它:

      //Cropping _image to fit it to the square by height or width
      
      CGFloat a = _image.size.height;
      CGFloat b = _image.size.width;
      CGRect cropRect;
      
      if (!(a==b)) {
          if (a<b) {
              cropRect = CGRectMake((b-a)/2.0, 0, a, a);
              b = a;
          }
          else if (b<a) {
              cropRect = CGRectMake(0, (a-b)/2.0, b, b);
              a = b;
          }
      
          CGImageRef imageRef = CGImageCreateWithImageInRect([_image CGImage], cropRect);
      
          UIImage* sourceImage = _image; 
          CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(imageRef);
          CGColorSpaceRef colorSpaceInfo = CGImageGetColorSpace(imageRef);
          CGContextRef bitmap;
          if (sourceImage.imageOrientation == UIImageOrientationUp || sourceImage.imageOrientation == UIImageOrientationDown) {
              bitmap = CGBitmapContextCreate(NULL, a, a, CGImageGetBitsPerComponent(imageRef), CGImageGetBytesPerRow(imageRef), colorSpaceInfo, bitmapInfo);
      
          } else {
              bitmap = CGBitmapContextCreate(NULL, a, a, CGImageGetBitsPerComponent(imageRef), CGImageGetBytesPerRow(imageRef), colorSpaceInfo, bitmapInfo);
          }
      
          if (sourceImage.imageOrientation == UIImageOrientationLeft) {
              CGContextRotateCTM (bitmap, radians(90));
              CGContextTranslateCTM (bitmap, 0, -a);
      
          } else if (sourceImage.imageOrientation == UIImageOrientationRight) {
              CGContextRotateCTM (bitmap, radians(-90));
              CGContextTranslateCTM (bitmap, -a, 0);
      
          } else if (sourceImage.imageOrientation == UIImageOrientationUp) {
              // NOTHING
          } else if (sourceImage.imageOrientation == UIImageOrientationDown) {
              CGContextTranslateCTM (bitmap, a, a);
              CGContextRotateCTM (bitmap, radians(-180.));
          }
      
          CGContextDrawImage(bitmap, CGRectMake(0, 0, a, a), imageRef);
          CGImageRef ref = CGBitmapContextCreateImage(bitmap);
          _image = [UIImage imageWithCGImage:ref];
          CGImageRelease(imageRef);
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多