【问题标题】:profile ImageView from several images来自多个图像的配置文件 ImageView
【发布时间】:2016-12-09 06:39:21
【问题描述】:

我需要实现个人资料 imageView 以与一定数量的成员聊天。

它应该看起来像这样:

因此,根据成员的数量,imageview 应该被分成适当的部分,这些部分应该由每个聊天成员的适当照片组成。

upd:我找到了一些解决方案(见下文)并且它有效,但是有些图像被拉伸了,因为它们的实际比例是 1:1。 如何按比例拉伸UIImage(比例为 1:1)以适合矩形大小?

class ProfileImageHelper {

    class func collageImage (rect:CGRect, images:[UIImage]) -> UIImage {

        let maxImagesPerRow = 2
        let maxSide = rect.width / CGFloat(maxImagesPerRow)

        var index = 0
        var currentRow = 1
        var xtransform:CGFloat = 0.0
        let transformOffset:CGFloat = 1.5

        var ytransform:CGFloat = 0.0
        var smallRect:CGRect = CGRect.zero

        UIGraphicsBeginImageContextWithOptions(rect.size, false, 0.0)//UIScreen.main.scale)

        for img in images {

            index += 1

            let x = index % maxImagesPerRow //row should change when modulus is 0

            //row changes when modulus of counter returns zero @ maxImagesPerRow
            if x == 0 {
                //last column of current row
                //xtransform += CGFloat(maxSide)
                smallRect = CGRect(x: xtransform, y: ytransform, width: maxSide - transformOffset, height: (rect.size.height / CGFloat(currentRow)) - transformOffset)

                //reset for new row
                currentRow += 1
                xtransform = 0.0
                ytransform = (maxSide * CGFloat(currentRow - 1)) + transformOffset

            } else {
                //not a new row
                if xtransform == 0 {
                    //this is first column
                    //draw rect at 0,ytransform
                    smallRect = CGRect(x: xtransform, y: ytransform, width: maxSide - transformOffset, height: (rect.size.height / CGFloat(currentRow)) - transformOffset)
                    xtransform += CGFloat(maxSide) + transformOffset
                } else {
                    //not the first column so translate x, ytransform to be reset for new rows only
                    smallRect = CGRect(x: xtransform, y: ytransform, width: maxSide - transformOffset, height: (rect.size.height / CGFloat(currentRow)) - transformOffset)
                    xtransform += CGFloat(maxSide) + transformOffset
                }
            }

            //draw in rect
            img.draw(in: smallRect)

        }

        let outputImage = UIGraphicsGetImageFromCurrentImageContext();

        UIGraphicsEndImageContext();

        return outputImage!
    }
}

有什么建议吗?

【问题讨论】:

  • 在 coregraphics 上绘制图像并作为 uiimage 返回。
  • 最好的方法是使用 3 个图像视图并在该图像视图中使用 breazerpath UIBezierPath 绘制 3 个不同图像的cornerradius
  • 一个 UIImageView 就足够了。为什么要为这么简单的组件浪费3个ImageView的资源??
  • 上图只是示例。我需要将任意数量的图像放在一个图像中,具体取决于聊天成员的数量。
  • 子类 uiimageview 以接受 uiimage 数组,使用数组的 .count 来决定图像的切片数,使用 GeneCode 建议的 coregraphics 将最终图像拼凑成图像视图

标签: ios objective-c swift uiimageview user-profile


【解决方案1】:

下面的代码应该允许您将图像粘贴到另一个图像之上。您可以使用 x/y 位置相应地移动图像。然后,您可以将最终图像裁剪为圆形。

UIImage *backrgoundImage = [[UIImage alloc] init];
backrgoundImage = image1;

UIImage *foregroundImage = [[UIImage alloc] init];
foregroundImage = image2;

UIGraphicsBeginImageContextWithOptions(backrgoundImage.size, FALSE, 0.0);
[backrgoundImage drawInRect:CGRectMake( 0, 0, backrgoundImage.size.width, backrgoundImage.size.height)];
[foregroundImage drawInRect:CGRectMake(backrgoundImage.size.width/2, backrgoundImage.size.height/2, foregroundImage.size.width, foregroundImage.size.height)];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(50, 50, 100, 100)];
[imageView setImage:newImage];

// Crop the final image to a circle
CALayer *imageLayer = imageView.layer;
[imageLayer setCornerRadius:imageView.frame.size.width/2];
[imageLayer setBorderWidth:1];
[imageLayer setMasksToBounds:YES];
imageLayer.borderColor = (__bridge CGColorRef _Nullable)([UIColor clearColor]);

[self.view addSubview:imageView];

【讨论】:

  • 谢谢我已经实现了类似的,但是由于 uiimage 没有 contentMode 属性,图像被拉伸了。
  • 对不起,草率的代码。我不在电脑前。请看我编辑的代码。这实际上对我有用,没有失真。处理图像时不需要 contentMode。确保在重叠图像时正确匹配坐标和大小。
  • 你能看到我更新的问题吗?我还发布了带有拉伸图像的示例。也许我的担忧会很明显。谢谢。
  • 图像很难看,但看起来图像在宽度维度上被挤压了。我最好的猜测是你定义的高度和宽度不尊重原始图像的规定。解决这个问题的最简单方法是在叠加之前将图像缩放到相同的大小。
【解决方案2】:

我用这个解决了我的问题:

class ProfileImageHelper {

    class func collageImage (size:CGSize, images:[UIImage]) -> UIImage {

        let maxImagesPerRow = 2
        let maxSide = size.width / CGFloat(maxImagesPerRow)

        var index = 0
        var currentRow = 1
        var xtransform:CGFloat = 0.0
        let transformOffset:CGFloat = 0.5
        var ytransform:CGFloat = 0.0
        var smallRect:CGRect = CGRect.zero

        UIGraphicsBeginImageContextWithOptions(size, false, UIScreen.main.scale)

        for img in images {

            index += 1

            if index == 5 { break }

            let x = index % maxImagesPerRow //row should change when modulus is 0

            //row changes when modulus of counter returns zero @ maxImagesPerRow
            if x == 0 {
                //last column of current row
                //get small image for two rows column
                if Int(images.count / 2) > 1 {
                    smallRect = CGRect(x: xtransform, y: ytransform, width: maxSide - transformOffset, height: (size.height / 2) - transformOffset)
                    img.draw(in: smallRect)
                //fit image to vertical column
                } else {
                    smallRect = CGRect(x: xtransform, y: ytransform, width: maxSide - transformOffset, height: size.height)
                    if let newImage = img.cropImageByMiddle() {
                        newImage.draw(in: smallRect)
                    }
                }

                //reset for new row
                currentRow += 1
                xtransform = 0.0
                ytransform = (maxSide * CGFloat(currentRow - 1)) + transformOffset

            } else {
                //not a new row
                if xtransform == 0 {
                    //this is first column
                    //draw rect at 0,ytransform
                    if images.count == 2 {
                        smallRect = CGRect(x: xtransform, y: ytransform, width: maxSide - transformOffset, height: size.height)
                        if let newImage = img.cropImageByMiddle() {
                            newImage.draw(in: smallRect)
                        }
                    } else {
                        smallRect = CGRect(x: xtransform, y: ytransform, width: maxSide - transformOffset, height: (size.height / 2) - transformOffset)
                        img.draw(in: smallRect)
                    }
                    xtransform += CGFloat(maxSide) + transformOffset
                }
            }
        }

        let outputImage = UIGraphicsGetImageFromCurrentImageContext();


        UIGraphicsEndImageContext();

        return outputImage!
    }
}

我裁剪图像,让中间部分适合垂直列。 为此我为UIImage写了扩展:

extension UIImage {
    func cropImageByMiddle() -> UIImage? {
        let cropRect = CGRect(x: self.size.width / 4, y: 0, width: self.size.width / 2, height: self.size.height)
        if let cgImg = self.cgImage {
            if let new = cgImg.cropping(to: cropRect) {
                return UIImage(cgImage: new)
            }
        }
        return nil
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多