7

任意のサイズのUIImageを指定すると、正方形の「アイコン」サイズのバージョンを生成し、pxピクセルを横に並べて、歪み (ストレッチ) なしで生成したいと考えています。しかし、私はちょっとした障害に遭遇しています。問題がどこにあるのかよくわかりません。これが私がこれまでに行っていることです。

まず、UImage sizeを指定して、次の 3 つのことを決定ratioします。a delta(目的のアイコン サイズと最も長い辺の差) と an offset(画像をクリッピングするときに原点座標を計算するために使用されます):

 if (size.width > size.height) {
   ratio = px / size.width;
   delta = (ratio*size.width - ratio*size.height);
   offset = CGPointMake(delta/2, 0);
 } else {
   ratio = px / size.height;
   delta = (ratio*size.height - ratio*size.width);
   offset = CGPointMake(0, delta/2);
 }

ここで、幅 640 ピクセル、高さ 480 ピクセルの画像があり、これから 50 ピクセル x 50 ピクセルのアイコンを取得したいとします。幅が高さよりも大きいため、計算は次のようになります。

ratio = 50px / 640px = 0.078125
delta = (ratio * 640px) - (ratio * 480px) = 50px - 37.5px = 12.5px
offset = {x=6.25, y=0}

次に、目的のアイコン サイズに歪みなくトリミングできる十分な大きさのCGRect と、クリッピング用の を作成します。rectclipRect

CGRect rect = CGRectMake(0.0, 0.0, (ratio * size.width) + delta,
                                   (ratio * size.height) + delta);
CGRect clipRect = CGRectMake(offset.x, offset.y, px, px);

上記の値を代入すると、次のようになります。

rect = origin {x=0.0, y=0.0}, size {width=62.5, height=50.0}
clipRect = origin {x=6.25, y=0}, size {width=50.0, height=50.0}

これで、作業する幅 62.5 ピクセル、高さ 50 ピクセルの四角形と、「中央」の 50x50 部分を取得するクリッピング四角形ができました。

ホームストレッチへ!次に、画像コンテキストを設定し、(ここで呼び出された) UIImagemyImageを rect に描画し、クリッピング四角形を設定し、(おそらく現在はクリップされた) 画像を取得して使用し、最後に画像コンテキストをクリーンアップします。

 UIGraphicsBeginImageContext(rect.size);
 [myImage drawInRect:rect]; 
 UIRectClip(clipRect);
 UIImage *icon = UIGraphicsGetImageFromCurrentImageContext();

 // Do something with the icon here ...

 UIGraphicsEndImageContext();

1 つだけ問題があります。クリッピングが発生しません。最終的に、幅 63px x 高さ 50px の画像になります。:(

おそらく私はUIRectClipを誤用/誤解していますか? rectとの使用を交換し、drawInRect:の前にUIRectClipclipRectを移動します。サイコロはありません。

この方法の例をオンラインでも検索してみましたが、役に立ちませんでした。レコードの場合、UIRectClipは次のように定義されます。

指定された四角形と交差することにより、現在のクリッピング パスを変更します。

物事をシャッフルすると、少し近づくことができます。

UIGraphicsBeginImageContext(clipRect.size);
UIRectClip(rect);
[myImage drawInRect:rect];

これで歪みはなくなりましたが、クリッピングされた画像は元の画像の中央に配置されていません。それでも、少なくとも画像は 50x50 ですが、上記のシャッフルの結果として変数名が汚れています。(名前の変更は、読者の演習として丁重に残しておきます。)

4

3 に答える 3

7

ユーレカ!私は物事が少し混乱していました。これは機能します:

CGRect clipRect = CGRectMake(-offset.x, -offset.y,
                             (ratio * size.width) + delta,
                             (ratio * size.height) + delta);
UIGraphicsBeginImageContext(CGSizeMake(px, px));
UIRectClip(clipRect);
[myImage drawInRect:clipRect];
UIImage *icon = UIGraphicsGetImageFromCurrentImageContext();

// Do something with the icon here ...

UIGraphicsEndImageContext();

もう必要ありませんrect。このトリックは、クリッピング四角形でのオフセットを使用しているように見えます。これにより、50 x 50 の画像を取得したい場所の原点が整列されます (この例では)。

おそらくもっと簡単な方法があります。もしそうなら、量ってください!

于 2009-09-10T15:47:24.933 に答える
1

同様のことを達成したかったのですが、元のポスターによる回答がうまくいかないことがわかりました。イメージを歪めました。これは、彼がソリューション全体を投稿せず、変数の初期化方法の一部を変更したためだけにある可能性があります。

 (if (size.width > size.height) 
       ratio = px / size.width;

私のソリューション(ソース画像から可能な限り最大の正方形を使用したかった)は間違っていました。また、UIClipRect を使用する必要はありません。コンテキストを抽出したい画像のサイズにすると、実際の描画はその rect の外側では行われません。画像 rect のサイズをスケーリングし、原点座標の 1 つをオフセットするだけです。以下に私の解決策を投稿しました:

+(UIImage *)makeIconImage:(UIImage *)image
{
    CGFloat destSize = 400.0;
    CGRect rect = CGRectMake(0, 0, destSize, destSize);

    UIGraphicsBeginImageContext(rect.size);

    if(image.size.width != image.size.height)
    {
        CGFloat ratio;
        CGRect destRect;

        if (image.size.width > image.size.height)
        {
            ratio = destSize / image.size.height;

            CGFloat destWidth = image.size.width * ratio;
            CGFloat destX = (destWidth - destSize) / 2.0;

            destRect = CGRectMake(-destX, 0, destWidth, destSize);

        }
        else
        {
            ratio = destSize / image.size.width;

            CGFloat destHeight = image.size.height * ratio;
            CGFloat destY = (destHeight - destSize) / 2.0;

            destRect = CGRectMake(0, destY, destSize, destHeight);
        }
        [image drawInRect:destRect];
    }
    else
    {
        [image drawInRect:rect];
    }
    UIImage *scaledImage = UIGraphicsGetImageFromCurrentImageContext();

    UIGraphicsEndImageContext();

    return scaledImage;
}
于 2014-03-06T11:48:05.157 に答える
0

wheeliebin の答えは正しいのですが、destY の前のマイナス記号を忘れていました

destRect = CGRectMake(0, -destY, destSize, destHeight);
于 2014-03-14T22:51:28.377 に答える