I'm using this method to compress UIImage
if (actualHeight > maxHeight || actualWidth > maxWidth)
{
if(imgRatio < maxRatio)
{
//adjust width according to maxHeight
imgRatio = maxHeight / actualHeight;
actualWidth = imgRatio * actualWidth;
actualHeight = maxHeight;
}
else if(imgRatio > maxRatio)
{
//adjust height according to maxWidth
imgRatio = maxWidth / actualWidth;
actualHeight = imgRatio * actualHeight;
actualWidth = maxWidth;
}
else
{
actualHeight = maxHeight;
actualWidth = maxWidth;
}
}
CGRect rect = CGRectMake(0.0, 0.0, actualWidth, actualHeight);
UIGraphicsBeginImageContext(rect.size);
[image drawInRect:rect];
UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
NSData *imageData = UIImageJPEGRepresentation(img, compressionQuality);
UIGraphicsEndImageContext();
But for some UIImage
, at the bottom of the of them, there is a 1 pixel white line. Any suggestions on what could be the cause?
Thank you so much!
The problem may be that you're working with CGFloats and you're multiplying/dividing them and this results in a non-integral coordinates.
Line
actualWidth = imgRatio * actualWidth;
and
actualHeight = imgRatio * actualHeight;
may cause a non integral coordinate. Use ceilf
or floorf
or roundf
to remedy this. E.g.
actualWidth = ceilf(imgRatio * actualWidth);
actualHeight = ceilf(imgRatio * actualHeight);
What happens without it
CGRect rect = CGRectMake(0.0, 0.0, actualWidth, actualHeight);
may actually be (0,0,24.33, 24.33)
You may actually be drawing a rect of this size, but image has to have a
round number of pixels for height and width, so Apple probably rounds the rect up to create the image context.
But then they probably draw it using antialiasing, so it really visually looks like non-integral pixels. And that's why you get the white line and possibly a loss of quality too.