UIImages / PNGの配列を取り込んで、垂直方向に順番につなぎ合わされたすべての画像の1つの背の高い画像を返す/保存するobjective-c関数を作成するのに助けが必要です。私はこれに慣れていないので、ゆっくり行って、それを楽にしてください:)
これまでの私の考え:UIViewを描画し、次に(画像の)それぞれの親にSubviewsを追加してから???
UIImages / PNGの配列を取り込んで、垂直方向に順番につなぎ合わされたすべての画像の1つの背の高い画像を返す/保存するobjective-c関数を作成するのに助けが必要です。私はこれに慣れていないので、ゆっくり行って、それを楽にしてください:)
これまでの私の考え:UIViewを描画し、次に(画像の)それぞれの親にSubviewsを追加してから???
通常の方法は、ビットマップイメージコンテキストを作成し、必要な位置にイメージを描画してから、イメージコンテキストからイメージを取得することです。
これはUIKitを使用して行うことができます。これはやや簡単ですが、スレッドセーフではないため、メインスレッドで実行する必要があり、UIがブロックされます。
このためのサンプルコードはたくさんありますが、正しく理解したい場合は、UIGraphicsContextBeginImageContext、UIGraphicsGetCurrentContext、UIGraphicsGetImageFromCurrentImageContext、UIImageDrawInRectを確認する必要があります。UIGraphicsPopCurrentContextを忘れないでください。
これは、バックグラウンドスレッドで安全に使用できるAFAIKであるCore Graphicsを使用して行うこともできます(まだクラッシュしていません)。UIKitは内部でCGを使用するだけなので、効率はほぼ同じです。このためのキーワードは、CGBitmapContextCreate、CGContextDrawImage、CGBitmapContextCreateImage、CGContextTranslateCTM、CGContextScaleCTM、およびCGContextRelease(コアグラフィックス用のARCなし)です。スケーリングと変換は、CGの原点が右下隅にあり、Yが上に向かって増加するためです。
3番目の方法もあります。これは、コンテキストにCGを使用しますが、CALayerを使用してすべての調整の苦痛を軽減し、コンテンツとしてCGImage(UIImage.CGImage)を設定してから、レイヤーをコンテキストにレンダリングします。これは依然としてスレッドセーフであり、レイヤーがすべての変換を処理できるようにします。このためのキーワードは--renderInContext:
私はここで少し遅れていることを知っていますが、うまくいけばこれが誰かを助けることができます. 配列から 1 つの大きな画像を作成しようとしている場合は、このメソッドを使用できます
- (UIImage *)mergeImagesFromArray: (NSArray *)imageArray {
if ([imageArray count] == 0) return nil;
UIImage *exampleImage = [imageArray firstObject];
CGSize imageSize = exampleImage.size;
CGSize finalSize = CGSizeMake(imageSize.width, imageSize.height * [imageArray count]);
UIGraphicsBeginImageContext(finalSize);
for (UIImage *image in imageArray) {
[image drawInRect: CGRectMake(0, imageSize.height * [imageArray indexOfObject: image],
imageSize.width, imageSize.height)];
}
UIImage *finalImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return finalImage;
}
スイフト4
extension Array where Element: UIImage {
func stitchImages(isVertical: Bool) -> UIImage {
let maxWidth = self.compactMap { $0.size.width }.max()
let maxHeight = self.compactMap { $0.size.height }.max()
let maxSize = CGSize(width: maxWidth ?? 0, height: maxHeight ?? 0)
let totalSize = isVertical ?
CGSize(width: maxSize.width, height: maxSize.height * (CGFloat)(self.count))
: CGSize(width: maxSize.width * (CGFloat)(self.count), height: maxSize.height)
let renderer = UIGraphicsImageRenderer(size: totalSize)
return renderer.image { (context) in
for (index, image) in self.enumerated() {
let rect = AVMakeRect(aspectRatio: image.size, insideRect: isVertical ?
CGRect(x: 0, y: maxSize.height * CGFloat(index), width: maxSize.width, height: maxSize.height) :
CGRect(x: maxSize.width * CGFloat(index), y: 0, width: maxSize.width, height: maxSize.height))
image.draw(in: rect)
}
}
}
}
このコードを試してください。2つの画像をつなぎ合わせて、ImageViewに表示してみました
UIImage *bottomImage = [UIImage imageNamed:@"bottom.png"]; //first image
UIImage *image = [UIImage imageNamed:@"top.png"]; //foreground image
CGSize newSize = CGSizeMake(209, 260); //size of image view
UIGraphicsBeginImageContext( newSize );
// drawing 1st image
[bottomImage drawInRect:CGRectMake(0,0,newSize.width/2,newSize.height/2)];
// drawing the 2nd image after the 1st
[image drawInRect:CGRectMake(0,newSize.height/2,newSize.width/2,newSize.height/2)] ;
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
join.image = newImage;
join はイメージビューの名前で、画像を 1 つの画像として見ることができます。