设置聊天泡泡颜色以及添加描边的方式

来源:互联网 发布:fc2最新域名2016 编辑:程序博客网 时间:2024/05/02 04:34

一种简易的聊天泡泡设置颜色以及添加描边的方式

遇到的问题

比如我现在有以下这个图片:

bubble_regular

然后我想做到以下这种效果:

sample

第一种方法

应该是最简单的一种方法,直接提供带描边的图片,在这里例子里就是提供一张篮框绿底的图片以及一张红框黄底的图片。

但是问题来了,如果需要提供多种配色方案怎么办?比如白天模式下是一种配色方案,夜晚模式下是另一种配色方案,或者哪天想把当前配色方案修改掉,这会导致程序里需要存储大量的图片。目前iOS每种图片都需要提供三种分辨率的图片,多一张图片就意味着其实要多三张图片。

还有一个问题就是,泡泡有两种方向,难道我们也需要提供两种图片吗?再结合第一个问题,好像我们需要提供很多图片。

第二种方法

这就是这篇文章所要阐述的方法。该方法就是由程序自动给图片上色。

让我们定义如下这个方法:

- (UIImage *)imageMaskedWithColor:(UIColor *)color {UIImage *bubbleImage = [UIImage imageNamed:@"bubble"];CGRect imageRect = CGRectMake(0.0f, 0.0f, bubbleImage.size.width, bubbleImage.size.height);UIImage *newImage = nil;    UIGraphicsBeginImageContextWithOptions(imageRect.size, NO, bubbleImage.scale);    {        CGContextRef context = UIGraphicsGetCurrentContext();                // 根据文档,使用这种方式展示图片会是上下颠倒的        // 因此先要将图片向下反转        CGContextScaleCTM(context, 1.0f, -1.0f);        // 反转之后再把反转后的图片移回到原来位置        CGContextTranslateCTM(context, 0.0f, -(imageRect.size.height));                CGContextClipToMask(context, imageRect, bubbleImage.CGImage);        // 填充所期望的颜色        CGContextSetFillColorWithColor(context, color.CGColor);        CGContextFillRect(context, imageRect);                // 生成新的图片返回        newImage = UIGraphicsGetImageFromCurrentImageContext();    }    UIGraphicsEndImageContext();    return newImage;}

该函数调用方式如下:

self.imageview.image = [self imageMaskedWithColor:[UIColor yellowColor]];

展示效果如下:

yellow_bubble

那接下来我们再来处理描边的问题。这里我也研究了很久,如果想纯粹用程序自动来做一个通用的非规则图片描边,目前看来好像比较困难(如果大家有比较好的办法,请不吝告知)。

因此我选择了相对简单的办法,就是直接用泡泡的图片把中间扣掉,然后生成一张描边图片,如以下图片:

bubble_stroke

然后我们直接使用上面的技术,分别为实心的泡泡图片和描边的泡泡图片填充想要的颜色,然后再把两种图片画在一起,这样一张带描边的实心泡泡图片就出来了。

让我们定义如下这个新的方法:

- (UIImage *)imageMaskedWithColor:(UIColor *)color strokeColor:(UIColor *)strokeColor {    UIImage *bubbleImage = [UIImage imageNamed:@"bubble"];    UIImage *strokeImage = [UIImage imageNamed:@"bubble_stroke"];    CGRect imageRect = CGRectMake(0.0f, 0.0f, bubbleImage.size.width, bubbleImage.size.height);    UIImage *newImage = nil;        UIGraphicsBeginImageContextWithOptions(imageRect.size, NO, bubbleImage.scale);    {        CGContextRef context = UIGraphicsGetCurrentContext();                CGContextScaleCTM(context, 1.0f, -1.0f);        CGContextTranslateCTM(context, 0.0f, -(imageRect.size.height));                // 设置底色        CGContextClipToMask(context, imageRect, bubbleImage.CGImage);        CGContextSetFillColorWithColor(context, color.CGColor);        CGContextFillRect(context, imageRect);                // 设置描边色        CGContextClipToMask(context, imageRect, strokeImage.CGImage);        CGContextSetFillColorWithColor(context, strokeColor.CGColor);        CGContextFillRect(context, imageRect);                newImage = UIGraphicsGetImageFromCurrentImageContext();    }    UIGraphicsEndImageContext();    return newImage;}

该函数调用方式如下:

self.imageview.image = [self strokeImageWithColor:[UIColor yellowColor]                                      strokeColor:[UIColor redColor]];

展示效果如下:

yellow_red_bubble

那我们还就剩下最后一个问题了,反向的泡泡怎么办?

我们在定义一个方法,用来使得泡泡图片转向:

- (UIImage *)horizontallyFlippedImageFromImage:(UIImage *)image{    return [UIImage imageWithCGImage:image.CGImage                               scale:image.scale                         orientation:UIImageOrientationUpMirrored];}

和之前定义的方法结合起来使用:

UIImage *newImage = [self strokeImageWithColor:[UIColor greenColor]                                   strokeColor:[UIColor blueColor]];self.imageview.image = [self horizontallyFlippedImageFromImage:newImage];

展示效果如下:

inverse_bubble

总结

到这里这次要介绍的内容都已经介绍完了,这篇博客所介绍方法的最大好处就是可以非常容易适应各种配色方案,同时提供了一种比较实用的描边方式,也解决图片过多导致程序无谓膨胀的问题。

当然也有缺点,比如描边的宽度无法自定义,除非重新截图。另外如果泡泡形状发生改变,也需要重新截图。

其实我这里使用的一些方法基本都来自于JSQMessagesViewController这个第三方库。

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 憋尿久了尿不出来怎么办 憋尿引起的总有尿意怎么办 如果孕妇憋尿了怎么办 孕妇憋尿半个月怎么办 尿憋久了排空后膀胱疼怎么办 胸疼肚子疼不规则流血怎么办 上小便下面会痛怎么办 两岁宝贝憋尿怎么办 打激素脸胖了怎么办 医生写的病历看不懂怎么办 怀孕尿蛋白3个加怎么办 两周岁宝宝牙齿坏掉怎么办 前列缐炎引起尿血怎么办 牙齿牙根长在神经里怎么办 牙齿杀完神经牙根发炎怎么办 牙齿有大洞好疼怎么办 大门牙有蛀牙了怎么办 大门牙蛀牙黑了怎么办 大门牙蛀牙有洞怎么办 大门牙的缝蛀了怎么办 最里面的牙烂了怎么办 牙齿蛀了个洞怎么办办 牙齿痛怎么办才能治好? 门牙牙齿蛀掉了怎么办 吃了辣的牙齿痛怎么办 牙颈部楔状缺损怎么办 牙齿磨了很疼怎么办 小孩牙有窟窿疼怎么办 西瓜吃多了尿不停怎么办 吃了个西瓜不停拉肚子怎么办 例假完了又来了怎么办 肾上面有个肿瘤怎么办 膀胱壁毛糙增厚怎么办 痔疮手术后尿不出来怎么办 小牛肚一天不尿怎么办 小孩拉肚一直不好怎么办 尿涨但是尿很少怎么办 十四岁尿血医生说是肾炎怎么办 吃肉反胃想吐怎么办 母牛排尿带血尿发烧怎么办 4岁发烧40度怎么办