web-dev-qa-db-fra.com

Redimensionner UIImage avec rapport d'aspect?

J'utilise ce code pour redimensionner une image sur l'iPhone:

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

Ce qui fonctionne très bien, tant que le rapport d'aspect de l'image correspond à celui de la nouvelle image redimensionnée. Je voudrais modifier cela afin qu'il conserve le rapport d'aspect correct et place juste un fond noir partout où l'image n'apparaît pas. Je finirais donc avec une image 320x480 mais avec du noir en haut et en bas ou sur les côtés, selon la taille de l'image d'origine.

Existe-t-il un moyen simple de procéder de la même manière que ce que je fais? Merci!

37
Cory Imdieke

Après avoir défini le rectangle de l'écran, procédez comme suit pour décider dans quel rect dessiner l'image:

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

Si vous ne voulez pas agrandir des images plus petites que screenRect, assurez-vous que factor est supérieur ou égal à un (par exemple factor = fmax(factor, 1)).

Pour obtenir le fond noir, vous voudrez probablement simplement définir la couleur du contexte sur noir et appeler fillRect avant de dessiner l'image.

55
Frank Schmitt

Je sais que c'est très ancien, mais merci pour ce message - il m'a redirigé d'essayer d'utiliser l'échelle pour dessiner l'image. Dans le cas où cela profite à quelqu'un, j'ai créé une classe d'extension que je lancerai ici. Il vous permet de redimensionner une image comme celle-ci:

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

Je n'ai pas besoin d'une option d'ajustement, mais elle pourrait facilement être étendue pour prendre également en charge 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;
    }
  }
}

Selon l'article ci-dessus, il commence un nouveau contexte pour une image, puis pour cette image, il comprend l'aspect et peint ensuite l'image. Si vous n'avez fait aucun Swift xcode dev time, UIGraphics est un peu en arrière sur la plupart des systèmes avec lesquels je travaille mais pas mal. Un problème est que les bitmaps par défaut peignent de bas en haut. Pour obtenir autour de ça,

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

Modifie l'orientation du dessin en haut à gauche en bas à droite ... mais vous devez également déplacer l'origine ainsi que le TranslateCTM.

Espérons que cela fera gagner du temps à quelqu'un.

À votre santé

0