简体   繁体   English

用宽高比调整UIImage的大小?

[英]Resize UIImage with aspect ratio?

I'm using this code to resize an image on the iPhone: 我正在使用以下代码来调整iPhone上图像的大小:

CGRect screenRect = CGRectMake(0, 0, 320.0, 480.0);
UIGraphicsBeginImageContext(screenRect.size);
[value drawInRect:screenRect blendMode:kCGBlendModePlusDarker alpha:1];
UIImage *tmpValue = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

Which is working great, as long as the aspect ratio of the image matches that of the new resized image. 只要图像的纵横比与新调整大小的图像的纵横比匹配,该方法就很好用。 I'd like to modify this so that it keeps the correct aspect ratio and just puts a black background anywhere the image doesn't show up. 我想对此进行修改,以使其保持正确的宽高比,并在未显示图像的任何地方放置黑色背景。 So I would still end up with a 320x480 image but with black on the top and bottom or sides, depending on the original image size. 因此,我仍然会得到一张320x480的图像,但顶部和底部或侧面为黑色,具体取决于原始图像的大小。

Is there an easy way to do this similar to what I'm doing? 有没有一种类似于我正在做的简单方法? Thanks! 谢谢!

After you set your screen rect, do something like the following to decide what rect to draw the image in: 设置屏幕矩形后,请执行以下类似操作,以决定在哪个矩形上绘制图像:

float hfactor = value.bounds.size.width / screenRect.size.width;
float vfactor = value.bounds.size.height / screenRect.size.height;

float factor = fmax(hfactor, vfactor);

// Divide the size by the greater of the vertical or horizontal shrinkage factor
float newWidth = value.bounds.size.width / factor;
float newHeight = value.bounds.size.height / factor;

// Then figure out if you need to offset it to center vertically or horizontally
float leftOffset = (screenRect.size.width - newWidth) / 2;
float topOffset = (screenRect.size.height - newHeight) / 2;

CGRect newRect = CGRectMake(leftOffset, topOffset, newWidth, newHeight);

If you don't want to enlarge images smaller than the screenRect, make sure factor is greater than or equal to one (eg factor = fmax(factor, 1) ). 如果您不想放大小于screenRect的图像,请确保factor大于或等于1(例如factor = fmax(factor, 1) )。

To get the black background, you would probably just want to set the context color to black and call fillRect before drawing the image. 要获得黑色背景,您可能只想将上下文颜色设置为黑色,并在绘制图像之前调用fillRect。

I know this is very old, but thanks for that post -- it redirected me from attempting to use scale to drawing the image. 我知道这很老了,但是感谢那篇文章-它使我从尝试使用比例尺重定向到绘制图像。 In case it is of benefit to anyone, I made an extension class I'll throw in here. 万一对任何人都有利,我做了一个扩展类,我将在这里进行介绍。 It allows you to resize an image like this: 它允许您调整图像的大小,如下所示:

      UIImage imgNew = img.Fit(40.0f, 40.0f);

I don't need a fit option, but it could easily be extended to support Fill as well. 我不需要合适的选项,但可以轻松扩展它以支持Fill。

using CoreGraphics;
using System;
using UIKit;

namespace SomeApp.iOS.Extensions
{
  public static class UIImageExtensions
  {
    public static CGSize Fit(this CGSize sizeImage,
      CGSize sizeTarget)
    {
      CGSize ret;
      float fw;
      float fh;
      float f;

      fw = (float) (sizeTarget.Width / sizeImage.Width);
      fh = (float) (sizeTarget.Height / sizeImage.Height);
      f = Math.Min(fw, fh);
      ret = new CGSize
      {
        Width = sizeImage.Width * f,
        Height = sizeImage.Height * f
      };
      return ret;
    }

    public static UIImage Fit(this UIImage image,
      float width,
      float height,
      bool opaque = false,
      float scale = 1.0f)
    {
      UIImage ret;

      ret = image.Fit(new CGSize(width, height),
        opaque,
        scale);
      return ret;
    }

    public static UIImage Fit(this UIImage image,
      CGSize sizeTarget,
      bool opaque = false,
      float scale = 1.0f)
    {
      CGSize sizeNewImage;
      CGSize size;
      UIImage ret;

      size = image.Size;
      sizeNewImage = size.Fit(sizeTarget);
      UIGraphics.BeginImageContextWithOptions(sizeNewImage,
        opaque,
        1.0f);
      using (CGContext context = UIGraphics.GetCurrentContext())
      {
        context.ScaleCTM(1, -1);
        context.TranslateCTM(0, -sizeNewImage.Height);
        context.DrawImage(new CGRect(CGPoint.Empty, sizeNewImage),
          image.CGImage);
        ret = UIGraphics.GetImageFromCurrentImageContext();
      }
      UIGraphics.EndImageContext();
      return ret;
    }
  }
}

As per the post above, it starts a new context for an image, then for that image it figures out aspect and then paints into the image. 按照上面的文章,它为图像启动了一个新的上下文,然后为该图像找出纵横比,然后绘制到图像中。 If you haven't done any Swift xcode dev time, UIGraphics is a bit backwards to most systems I work with but not bad. 如果您还没有完成任何Swift xcode开发时间,那么UIGraphics对于我使用的大多数系统都会有些落后,但还不错。 One issue is that bitmaps by default paint bottom to top. 一个问题是,默认情况下,位图从下至上绘制。 To get around that, 为了解决这个问题,

        context.ScaleCTM(1, -1);
        context.TranslateCTM(0, -sizeNewImage.Height);

Changes the orientation of drawing to the more common top-left to bottom-right... but then you need to move the origin as well hence the TranslateCTM. 将图形的方向更改为更常见的左上角到右下角...,但是随后还需要移动原点,因此也需要移动TranslateCTM。

Hopefully, it saves someone some time. 希望它可以节省一些时间。

Cheers 干杯

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM