【问题标题】:Resize UIImage with aspect ratio?用纵横比调整 UIImage 的大小?
【发布时间】:2010-12-14 18:10:18
【问题描述】:

我正在使用此代码在 iPhone 上调整图像大小:

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

只要图像的纵横比与调整后的新图像的纵横比相匹配,效果就很好。我想修改它,使其保持正确的纵横比,并在图像未显示的任何地方放置黑色背景。所以我最终还是会得到一个 320x480 的图像,但顶部和底部或侧面都是黑色的,具体取决于原始图像大小。

有没有一种类似于我正在做的简单方法来做到这一点?谢谢!

【问题讨论】:

标签: ios iphone uiimage core-graphics


【解决方案1】:

设置屏幕矩形后,请执行以下操作来决定在哪个矩形中绘制图像:

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);

如果您不想放大小于 screenRect 的图像,请确保 factor 大于或等于一(例如 factor = fmax(factor, 1))。

要获得黑色背景,您可能只想将上下文颜色设置为黑色并在绘制图像之前调用 fillRect。

【讨论】:

  • value 是 Cory 用来存储源图像的变量。
  • @Frank Schmitt,我可以检查一下如何将这种情况下的上下文设置为黑色吗?
  • 我得到了编译器抛出的“函数'max'的隐式声明”,即使我记得包含 math.h(我正在使用 XCode 4.0)更改:float factor = max( … 到 @987654326 @全部大写)解决了这个问题。 FWIW 我需要重新调整 UIImage(而不是 UIImageView)的原因是因为我将图像设置在默认样式的 UITableCell 中。这帮助我避免了实现自定义 UITableCell。 感谢 Frank 的出色解决方案!
  • 刚刚进行了编辑以使用 fmax,它已经在 Apple 包含的任何预编译头文件中。与 MAX() 的区别在于它将所有内容都视为整数,而 Core Graphics 对所有坐标值本机使用 CGFloats(双精度)。所以在 Retina 屏幕上,你的方法可能会偏离半点:)
  • @iOS_Ramesh value 是您正在调整大小的UIImage
【解决方案2】:

我知道这已经很老了,但感谢那篇文章——它让我不再尝试使用比例来绘制图像。万一它对任何人都有好处,我做了一个扩展类,我会放在这里。它允许您像这样调整图像的大小:

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

我不需要 fit 选项,但它也可以轻松扩展以支持 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;
    }
  }
}

根据上面的帖子,它为图像启动一个新的上下文,然后为该图像计算出纵横比,然后绘制到图像中。如果您还没有完成任何 Swift xcode 开发时间,那么 UIGraphics 与我使用的大多数系统相比有点倒退,但还不错。一个问题是位图默认从下到上绘制。为了解决这个问题,

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

将绘图的方向更改为更常见的左上角到右下角...但是您还需要移动原点,因此需要移动 TranslateCTM。

希望它可以节省一些时间。

干杯

【讨论】:

    猜你喜欢
    • 2011-11-30
    • 2017-08-10
    • 2012-05-26
    • 2011-10-05
    • 2012-02-24
    • 2022-01-23
    • 2012-11-16
    • 1970-01-01
    • 2020-06-14
    相关资源
    最近更新 更多