博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
图像滤镜艺术--Toaster滤镜
阅读量:6174 次
发布时间:2019-06-21

本文共 4700 字,大约阅读时间需要 15 分钟。

原文:

    根据Instagram CEO的说法,Toaster滤镜是Instagram所有滤镜中最复杂的滤镜,这个滤镜给人一种新奇的红色烘烤感,很能让人联想起这个Toaster单词的本意呵呵,今天我将用C#实现这个滤镜,当然我也只是探索,如何逼近它的效果,差异的存在在所难免,大家勿怪哦。

    按照之前的说法,还是先使用Photoshop进行模拟,然后根据模拟步骤,进行C#代码编写。

首先,看下效果图:

 

                                                               (a)PS效果图

                                                             (b)Instagram效果图

                                                         (c)C#代码效果图

    效果怎么样我说了不算呵呵,下面介绍PS实现步骤:

    1,打开测试图像,命名为图层Source

    2,创建三个模板,这里三个模板我已经给大家提供,在下载包里,当然这三个模板是我根据Instagram变换出来的,大家只需要拿来使用就行了,将三个模板分别命名为a,b,c,如下图所示:

    3,对图层a执行"混合图层"---"正片叠底"

    4,对图层b执行"混合图层"---"滤色":

    5,对图层c执行"混合图层"---"柔光":

    这样效果图就出来了,看起来是不是相当简单呢?

    下面我们介绍C#代码实现:

    这里实现的关键也就是讲三个图层分别按照相应的图层混合模式混合起来就可以了,我这里新建了一个ToasterFilter的类,代码如下:

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Drawing;using System.Drawing.Imaging;namespace SpecialeffectDemo{    unsafe class ToasterFilter    {        public ToasterFilter(Bitmap src,Bitmap bg_a,Bitmap bg_b,Bitmap bg_c)        {            this.srcBitmap = src;            this.mapa = bg_a;            this.mapb = bg_b;            this.mapc = bg_c;        }        private Bitmap srcBitmap = null;        private Bitmap mapa = null;        private Bitmap mapb = null;        private Bitmap mapc = null;        public Bitmap Apply()        {            if (srcBitmap != null)            {                Bitmap src = new Bitmap(srcBitmap);                int w = srcBitmap.Width;                int h = srcBitmap.Height;                BitmapData srcData = src.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);                BitmapData mapaData = mapa.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);                BitmapData mapbData = mapb.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);                BitmapData mapcData = mapc.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);                byte* p = (byte*)srcData.Scan0;                byte* pa = (byte*)mapaData.Scan0;                byte* pb = (byte*)mapbData.Scan0;                byte* pc = (byte*)mapcData.Scan0;                int r = 0, g = 0, b = 0, a = 0, t = 0;                for (int j = 0; j < h; j++)                {                    for (int i = 0; i < w; i++)                    {                        b = p[0];                        g = p[1];                        r = p[2];                                                b = SpecialEffectClass.ModeMultiplyEffect(b, pa[0]);                        g = SpecialEffectClass.ModeMultiplyEffect(g, pa[1]);                        r = SpecialEffectClass.ModeMultiplyEffect(r, pa[2]);                        b = SpecialEffectClass.ModeFilterColorEffect(b, pb[0]);                        g = SpecialEffectClass.ModeFilterColorEffect(g, pb[1]);                        r = SpecialEffectClass.ModeFilterColorEffect(r, pb[2]);                        a = pc[3];                        if (a == 255)//由于模板图像中存在透明度变化,因此选用32位bgra格式                        {                            b = SpecialEffectClass.ModeSmoothLightEffect(b, pc[0]);                            g = SpecialEffectClass.ModeSmoothLightEffect(g, pc[1]);                            r = SpecialEffectClass.ModeSmoothLightEffect(r, pc[2]);                        }                        else                        {                            t = SpecialEffectClass.ModeSmoothLightEffect(b, pc[0]);                            b = (b * (255 - a) + t * a)/255;                            t = SpecialEffectClass.ModeSmoothLightEffect(g, pc[1]);                            g = (g * (255 - a) + t * a)/255;                            t = SpecialEffectClass.ModeSmoothLightEffect(r, pc[2]);                            r = (r * (255 - a) + t * a)/255;                        }                        p[0] = (byte)b;                        p[1] = (byte)g;                        p[2] = (byte)r;                        p += 4;                        pa += 4;                        pb += 4;                        pc += 4;                    }                    p += srcData.Stride - w * 4;                    pa += mapaData.Stride - w * 4;                    pb += mapbData.Stride - w * 4;                    pc += mapcData.Stride - w * 4;                }                src.UnlockBits(srcData);                mapa.UnlockBits(mapaData);                mapb.UnlockBits(mapbData);                mapc.UnlockBits(mapcData);                return src;            }            else            {                return null;            }        }           }}

注意:由于图层C是具有不同的透明度的,因此,我们在程序中要使用PixelFormat.Format32bppArgb,而不再是24位;

程序效果图稍微偏暗,大家可以调整一下亮度即可,最后,放上Demo的下载链接,当然,里面有两个包,一个是Photoshop文件,供大家进行PS实践检验,一个是C#的Demo:

如有问题,联系我。邮箱:

 

最后,分享一个专业的图像处理网站(微像素),里面有很多源代码下载:

你可能感兴趣的文章
移动web开发之像素和DPR
查看>>
nginx+tomcat+redis实现session共享
查看>>
UWP VirtualizedVariableSizedGridView 支持可虚拟化可变大小Item的View(二)
查看>>
rsync 介绍
查看>>
做一个合格的Team Leader -- 基本概念
查看>>
leetcode 190 Reverse Bits
查看>>
阿里巴巴发布AliOS品牌 重投汽车及IoT领域
查看>>
OPENCV图像处理(二):模糊
查看>>
glassfish4系统启动脚本
查看>>
VMware 虚拟化编程(13) — VMware 虚拟机的备份方案设计
查看>>
独家 | 一文读懂推荐系统知识体系-下(评估、实战、学习资料)
查看>>
UIEvent&amp;nbsp;UIResponder&amp;nbsp;UI_04
查看>>
从非GP到GP
查看>>
云计算助力CDN加速
查看>>
iphone开发之多线程NSThread和NSInvocationOperation
查看>>
MFMailComposeViewController 发邮件
查看>>
velocity 模板解析类
查看>>
HTTP以及HTTPS协议
查看>>
Browser:浏览器版本判断类
查看>>
MyEclipse Servers视窗出现“Could not create the view: An unexpected exception was thrown”错误解决办法...
查看>>