2016-03-04 3 views
0

Предполагается, что у меня есть объект UIImage на UIViewController, и я хочу установить изображение с контроллера. В основном то, что я хочу сделать, это, слияние двух изображений вместе, что первое изображение является 5 звезда с синим цветом:Resize and Crop 2 Изображения повлияли на исходное качество изображения

enter image description here

и второе изображение является 5 звезд серым цветом:

enter image description here

Предназначен для оценки изображения. Поскольку максимальный рейтинг равен 5, я должен умножить его на 20, чтобы получить 100 очков, чтобы сделать расчет легче. Подробнее см. Код.

Так что у меня это (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):

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

Код работает отлично, но слитое изображение настолько низкое по качеству, хотя я использую изображение высокого качества. Это изображение 3,7 рейтинга:

enter image description here

Что я должен сделать, чтобы объединить изображения без терять оригинальное качество? Благодарю.

+0

вы можете добавить этот код, где вы звоните метод getRatingImageBasedOnRating – Johnykutty

+0

Проверьте, возвращают ли ваши методы BM_ImageHelper.resize и 'BM_ImageHelper.crop' изображения желаемого качества – Johnykutty

+0

Привет @Johnykutty, извините, я забыл прикрепить класс BM_ImageHelper .. Прикрепленный файл сейчас. Спасибо –

ответ

2

В вашем методе BM_ImageHelper.resize дается шкала 1.0. Это должны быть экраны устройств.

Изменить его

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

UPDATE

изменить Также ваш метод кадрирования с учетом масштабов, как

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 
} 
+0

Не работает, изображение на экране становится больше желаемого. –

+0

@ mrjimoy_05 проверить это сейчас – Johnykutty

+0

Ничего себе, это работает как шарм, спасибо :) –