调整大小和裁剪 2 图像影响原始图像质量 [英] Resize and Crop 2 Images affected the original image quality

查看:30
本文介绍了调整大小和裁剪 2 图像影响原始图像质量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我在 UIViewController 上有一个 UIImage 的对象,并且我想从 Controller 设置图像.基本上我想要做的是,将两个图像合并在一起,第一个图像是蓝色的 5 星:

Supposed that I have a UIImage's object on the UIViewController, and I want to set the image from the Controller. Basically what I want to do is, merging two images together, that the first image is the 5 star with blue color :

第二张图片是灰色的 5 星:

and the second image is the 5 star with grey color :

它用于评价图像.由于最大评分为 5,那么我必须将其乘以 20 以获得 100 分,以使计算更容易.详细逻辑请看代码.

It's intended for rating image. Since the maximum rating is 5, then I have to multiply it by 20 to get 100 point to make the calculation easier. Please see code for more details logic.

所以我有这个 (BM_RatingHelper.swift):

static func getRatingImageBasedOnRating(rating: CGFloat, width: CGFloat, height: CGFloat) -> UIImage {
    // available maximum rating is 5.0, so we have to multiply it by 20 to achieve 100.0 point
    let ratingImageWidth = ( width / 100.0 ) * ( rating * 20.0 )

    // get active rating image
    let activeRatingImage = BM_ImageHelper.resize(UIImage(named: "StarRatingFullActive")!, targetSize: CGSize(width: width, height: height))
    let activeRatingImageView = UIImageView(frame: CGRectMake(0, 0, ratingImageWidth, height));
    activeRatingImageView.image = BM_ImageHelper.crop(activeRatingImage, x: 0, y: 0, width: ratingImageWidth, height: height);

    // get inactive rating image
    let inactiveRatingImage = BM_ImageHelper.resize(UIImage(named: "StarRatingFullInactive")!, targetSize: CGSize(width: width, height: height))
    let inactiveRatingImageView = UIImageView(frame: CGRectMake(ratingImageWidth, 0, ( 100.0 - ratingImageWidth ), height));
    inactiveRatingImageView.image = BM_ImageHelper.crop(inactiveRatingImage, x: ratingImageWidth, y: 0, width: ( 100.0 - ratingImageWidth ), height: height);

    // combine the images
    let ratingView = UIView.init(frame: CGRect(x: 0, y: 0, width: width, height: height))
    ratingView.backgroundColor = BM_Color.colorForType(BM_ColorType.ColorWhiteTransparent)
    ratingView.addSubview(activeRatingImageView)
    ratingView.addSubview(inactiveRatingImageView)

    return ratingView.capture()
}

BM_ImageHelper.swift :

import UIKit

class BM_ImageHelper: NSObject {

    // http://stackoverflow.com/questions/158914/cropping-an-uiimage
    static func crop(image: UIImage, x: CGFloat, y: CGFloat, width: CGFloat, height: CGFloat) -> UIImage {
        let rect = CGRect(x: x, y: y, width: width, height: height)
        let imageRef = CGImageCreateWithImageInRect(image.CGImage, rect)!
        let croppedImage = UIImage(CGImage: imageRef)
        return croppedImage
    }

    // http://iosdevcenters.blogspot.com/2015/12/how-to-resize-image-in-swift-in-ios.html
    static func resize(image: UIImage, targetSize: CGSize) -> UIImage {
        let size = image.size
        let widthRatio  = targetSize.width  / image.size.width
        let heightRatio = targetSize.height / image.size.height

        // Figure out what our orientation is, and use that to form the rectangle
        var newSize: CGSize

        if(widthRatio > heightRatio) {
            newSize = CGSizeMake(size.width * heightRatio, size.height * heightRatio)
        } else {
            newSize = CGSizeMake(size.width * widthRatio,  size.height * widthRatio)
        }

        // This is the rect that we've calculated out and this is what is actually used below
        let rect = CGRectMake(0, 0, newSize.width, newSize.height)

        // Actually do the resizing to the rect using the ImageContext stuff
        UIGraphicsBeginImageContextWithOptions(newSize, false, 1.0)
        image.drawInRect(rect)

        let newImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        return newImage
    }
}

extension UIView {

    // http://stackoverflow.com/a/34895760/897733
    func capture() -> UIImage {
        UIGraphicsBeginImageContextWithOptions(self.frame.size, self.opaque, UIScreen.mainScreen().scale)
        self.layer.renderInContext(UIGraphicsGetCurrentContext()!)
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        return image
    }

}

我称这个函数为(假设需要填充的图像是ratingImage):

I call that function like (supposed that the image need to filled is ratingImage) :

self.ratingImage.image =
    BM_RatingHelper.getRatingImageBasedOnRating(3.7, width: 100.0, height: 20.0)

代码运行良好,但合并后的图像质量很低,尽管我使用了高质量的图像.这是 3.7 评级的图像:

The code works perfectly, but the merged image is so low in quality although I have use the high quality image. This is the image for 3.7 rating :

我应该怎么做才能在不损失原始质量的情况下合并图像?谢谢.

What should I do to merge the images without lose the original quality? Thanks.

推荐答案

在你的 BM_ImageHelper.resize 方法中,它给出了 1.0 的比例.应该是设备的屏幕比例.

In your BM_ImageHelper.resize method its giving the scale 1.0. It should be the devices's screens scale.

改成

UIGraphicsBeginImageContextWithOptions(newSize, false,  UIScreen.mainScreen().scale)

更新

还要更改您的裁剪方法以解决比例问题,例如

Also change your crop method to address the scale, like

static func crop(image: UIImage, x: CGFloat, y: CGFloat, width: CGFloat, height: CGFloat) -> UIImage {
    let transform = CGAffineTransformMakeScale(image.scale, image.scale)
    let rect = CGRect(x: x, y: y, width: width, height: height)
    let transformedCropRect = CGRectApplyAffineTransform(rect, transform);
    let imageRef = CGImageCreateWithImageInRect(image.CGImage, transformedCropRect)!
    let croppedImage = UIImage(CGImage: imageRef, scale: image.scale, orientation: image.imageOrientation)

    return croppedImage
}

这篇关于调整大小和裁剪 2 图像影响原始图像质量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆