8

ここに画像の説明を入力してください

UIImageView内の画像を切り抜いて、新しいUIImageを作成したいと思います。たとえば、上の写真では、緑色で囲まれた領域の新しいUIImageが必要です。これを行うコードを見つけました。通常は次のようになります(UIImageカテゴリとして):

- (UIImage *)croppedImage:(CGRect)bounds {
    CGImageRef imageRef = CGImageCreateWithImageInRect([self CGImage], bounds);
    UIImage *croppedImage = [UIImage imageWithCGImage:imageRef];
    CGImageRelease(imageRef);
    return croppedImage;
}

完全に理にかなっています。ただし、私のUIImageViewはcontentModeの「アスペクトフィット」です。そのように、CGImageCreateWithImageInRectのCGRect計算が複雑になり、正しい解決策を見つけることができませんでした。

画像に行ったのと同じ変換を緑の長方形に適用する必要があると思いますか?

また、この別の質問(UIImageViewで画像にアスペクトフィットを適用した後の画像サイズを知る方法)を見つけました。これは、サイズを取得するブルートフォースの方法を示しているようですが、それがどのように収まるかはまだわかりませんトリミングの状況。

何か案は?

編集:私の場合、UIImageView上のオーバーレイビューに描かれた上記のような正方形が文字通りあります。したがって、UIImage(UIImageView内)をトリミングしていることに気付いたときに、緑色のCGRectを変更して、「アスペクトフィット」が適用されたときに実行される変換と「一致」するようにする必要があります。たとえば、UIImageViewを「左上」モードのままにすると、基になるUIImageとUIImageViewの間に1:1のマッピングがあるため、すべてが正常に機能します。「左上」モードの問題は、UIImageViewよりも大きい可能性があるため、画像全体が常に表示されるとは限らないことです。

4

4 に答える 4

10

同様の質問に対する他の回答に基づいて、UIImageViewカテゴリ用にこのメソッドを作成しました。

-(CGRect) cropRectForFrame:(CGRect)frame
{
    NSAssert(self.contentMode == UIViewContentModeScaleAspectFit, @"content mode must be aspect fit");

    CGFloat widthScale = self.bounds.size.width / self.image.size.width;
    CGFloat heightScale = self.bounds.size.height / self.image.size.height;

    float x, y, w, h, offset;
    if (widthScale<heightScale) {
        offset = (self.bounds.size.height - (self.image.size.height*widthScale))/2;
        x = frame.origin.x / widthScale;
        y = (frame.origin.y-offset) / widthScale;
        w = frame.size.width / widthScale;
        h = frame.size.height / widthScale;
    } else {
        offset = (self.bounds.size.width - (self.image.size.width*heightScale))/2;
        x = (frame.origin.x-offset) / heightScale;
        y = frame.origin.y / heightScale;
        w = frame.size.width / heightScale;
        h = frame.size.height / heightScale;
    }
    return CGRectMake(x, y, w, h);
}

緑の四角形のフレームを渡し(画像ビューのサブビューであると想定)、UIImageを切り抜くために切り抜きを元に戻すことができます。「アスペクトフィット」モードでのみ機能することに注意してください。私はそれをテストしていません。だから、それがうまくいくかどうか教えてください!

于 2012-06-02T20:07:13.390 に答える
4

答えはわかっていますが、上手くいくのに問題があったので、解決策も投稿しません。

問題は、画像がアスペクトフィットで拡大縮小されることですが、幅と高さの両方の倍率がわかっています。次に、適切なトリミング長方形を非常に簡単に計算できます。

-(UIImage*)crop:(CGRect)frame
{
    // Find the scalefactors  UIImageView's widht and height / UIImage width and height
    CGFloat widthScale = self.bounds.size.width / self.image.size.width;
    CGFloat heightScale = self.bounds.size.height / self.image.size.height;

    // Calculate the right crop rectangle 
    frame.origin.x = frame.origin.x * (1 / widthScale);
    frame.origin.y = frame.origin.y * (1 / heightScale);
    frame.size.width = frame.size.width * (1 / widthScale);
    frame.size.height = frame.size.height * (1 / heightScale);

    // Create a new UIImage
    CGImageRef imageRef = CGImageCreateWithImageInRect(self.image.CGImage, frame);
    UIImage *croppedImage = [UIImage imageWithCGImage:imageRef];
    CGImageRelease(imageRef);

    return croppedImage;
}
于 2012-08-28T15:20:26.657 に答える
1

自分が何をしているのかわからないと思います。UIImageViewを「切り抜く」ことはできません。UIImagesのみです。したがって、croppedImageメソッドは、UIImageViewカテゴリではなく、UIImageカテゴリにある必要があります。切り抜きメソッドに渡す境界線は、imageviewの境界ではなく、画像サイズに関連している必要があります。画像ビューのcontentModeが何であるかは関係ありません。画像のトリミングは、常に同じように機能します。まず、画像ビューから画像を取得します。次に、そこから新しいトリミングされた画像を作成し、最後に画像ビューのトリミングされた画像を設定します。これは、1行のコードで実行できます。

imageView.image = [imageView.image croppedImage:rect];

contentModeは「アスペクトフィット」であるため、新しい画像はビューフレームに収まるように自動的に拡大されます。ピクセル化の影響を回避するために、image.sizeに基づいてビューフレームを変更することもできます。

于 2012-06-02T10:09:34.823 に答える
0

以下の方法を使用します。

-(UIImage *)getNeedImageFrom:(UIImage*)image cropRect:(CGRect)rect
{
   CGSize cropSize = rect.size;
   CGFloat widthScale =  
   image.size.width/self.imageViewOriginal.bounds.size.width;
   CGFloat heightScale = 
   image.size.height/self.imageViewOriginal.bounds.size.height;
   cropSize = CGSizeMake(rect.size.width*widthScale,  
   rect.size.height*heightScale);
   CGPoint  pointCrop = CGPointMake(rect.origin.x*widthScale, 
   rect.origin.y*heightScale);
   rect = CGRectMake(pointCrop.x, pointCrop.y, cropSize.width, 
   cropSize.height);
   CGImageRef subImage = CGImageCreateWithImageInRect(image.CGImage, rect);
   UIImage *croppedImage = [UIImage imageWithCGImage:subImage];
   CGImageRelease(subImage);
   return croppedImage;

   }
于 2016-01-29T12:58:10.337 に答える