C#,图片分层(Layer Bitmap)绘制,反色、高斯模糊及凹凸贴图等处理的高速算法与源程序

1 图像反色Invert

对图像处理的过程中会遇到一些场景需要将图片反色,反色就是取像素的互补色,比如当前像素是0X00FFFF,对其取反色就是0XFFFFFF – 0X00FFFF = 0XFF0000,依次对图像中的每个像素这样做,最后得到的就是原始2 图像的反色。
 

2 高斯模糊(Gauss Blur)算法

高斯模糊(英语:Gaussian Blur),也叫高斯平滑,是在Adobe Photoshop、GIMP以及Paint.NET等图像处理软件中广泛使用的处理效果,通常用它来减少图像噪声以及降低细节层次。这种模糊技术生成的图像,其视觉效果就像是经过一个毛玻璃在观察图像,这与镜头焦外成像效果散景以及普通照明阴影中的效果都明显不同。高斯平滑也用于计算机视觉算法中的预先处理阶段,以增强图像在不同比例大小下的图像效果(参见尺度空间表示以及尺度空间实现)。 从数学的角度来看,图像的高斯模糊过程就是图像与正态分布做卷积。由于正态分布又叫作高斯分布,所以这项技术就叫作高斯模糊。图像与圆形方框模糊做卷积将会生成更加精确的焦外成像效果。由于高斯函数的傅立叶变换是另外一个高斯函数,所以高斯模糊对于图像来说就是一个低通滤波器。


3 凹凸贴图bump map

所有物体表面多少都会有一点凹凸的质感,但建模时如果需要再现这些质感,一个一个建或雕刻就太麻烦了。 bump maps这个参数就是利用光线和阴影的控制去制造凹凸质感的假象,但毕竟是利用光线,所以如果是特写镜头或特定角度(平面)还是会漏馅。
 

参考:

C#,图片像素(Bitmap Pixel)的读取与绘制的快速方法与源程序icon-default.png?t=O83Ahttps://blog.csdn.net/beijinghorn/article/details/125253281

4 源代码 Layer.cs:

using System;
using System.Text;
using System.Collections;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;class Layer : ICloneable
{internal FastBitmap _bitmap;private FastBitmap _mask;public Double _opacity;private Int32 _offsetx, _offsety;public Layer(Int32 width, Int32 height){_bitmap = new FastBitmap(width, height, PixelFormat.Format32bppArgb);Clear(Color.Transparent);_opacity = 1.0;}public Double Opacity{get { return _opacity; }set	{ _opacity = value; }}public FastBitmap Bitmap{get { return _bitmap; }}public FastBitmap Mask{get { return _mask; }set { _mask = value; }}public Int32 OffsetX{get { return _offsetx; }set { _offsetx = value; }}public Int32 OffsetY{get { return _offsety; }set { _offsety = value; }}public Object Clone(){Layer clone = new Layer(_bitmap.Width, _bitmap.Height);clone._bitmap = (FastBitmap)_bitmap.Clone();return clone;}public void Clear(Color c){_bitmap.Lock();for (Int32 y = 0; y < _bitmap.Height; y++)for (Int32 x = 0; x < _bitmap.Width; x++)_bitmap.SetPixel(x, y, c);_bitmap.Unlock();}public void DrawText(Int32 x, Int32 y, String text, Font font,Brush brush){Graphics g = Graphics.FromImage(_bitmap._bitmap);g.DrawString(text, font, brush, x, y, StringFormat.GenericTypographic);g.Dispose();}public void FillRectangle(Int32 x, Int32 y, Int32 width,Int32 height, Brush brush){Graphics g = Graphics.FromImage(_bitmap._bitmap);g.FillRectangle(brush, x, y, width, height);g.Dispose();}public Color GetPixel(Int32 x, Int32 y){return _bitmap.GetPixel(x, y);}public void Invert(){_bitmap.Lock();for (Int32 y = 0; y < _bitmap.Height; y++) {for (Int32 x = 0; x < _bitmap.Width; x++) {Color c = _bitmap.GetPixel(x, y);_bitmap.SetPixel(x, y, Color.FromArgb(c.A,255 - c.R, 255 - c.G, 255 - c.B));}}_bitmap.Unlock();}private Single Gauss(Single x, Single middle, Single width){if (width == 0)return 1F;Double t = - (1.0 / width) * ((middle - x) * (middle - x));return (Single)Math.Pow(Math.E, t);}public void Blur(Int32 horz, Int32 vert){Single weightsum;Single[] weights;FastBitmap t = (FastBitmap)_bitmap.Clone();_bitmap.Lock();t.Lock();weights = new Single[horz * 2 + 1];for (Int32 i = 0; i < horz * 2 + 1; i++) {Single y = Gauss(-horz + i, 0, horz);weights[i] = y;}for (Int32 row = 0; row < _bitmap.Height; row++) {for (Int32 col = 0; col < _bitmap.Width; col++) {Double r = 0;Double g = 0;Double b = 0;weightsum = 0;for (Int32 i = 0; i < horz * 2 + 1; i++) {Int32 x = col - horz + i;if (x < 0) {i += -x;x = 0;}if (x > _bitmap.Width - 1)break;Color c = _bitmap.GetPixel(x, row);r += c.R * weights[i];g += c.G * weights[i];b += c.B * weights[i];weightsum += weights[i];}r /= weightsum;g /= weightsum;b /= weightsum;Byte br = (Byte)Math.Round(r);Byte bg = (Byte)Math.Round(g);Byte bb = (Byte)Math.Round(b);if (br > 255) br = 255;if (bg > 255) bg = 255;if (bb > 255) bb = 255;t.SetPixel(col, row, Color.FromArgb(br, bg, bb));}}weights = new Single[vert * 2 + 1];for (Int32 i = 0; i < vert * 2 + 1; i++) {Single y = Gauss(-vert + i, 0, vert);weights[i] = y;}for (Int32 col = 0; col < _bitmap.Width; col++) {for (Int32 row = 0; row < _bitmap.Height; row++) {Double r = 0;Double g = 0;Double b = 0;weightsum = 0;for (Int32 i = 0; i < vert * 2 + 1; i++) {Int32 y = row - vert + i;if (y < 0) {i += -y;y = 0;}if (y > _bitmap.Height - 1)break;Color c = t.GetPixel(col, y);r += c.R * weights[i];g += c.G * weights[i];b += c.B * weights[i];weightsum += weights[i];}r /= weightsum;g /= weightsum;b /= weightsum;Byte br = (Byte)Math.Round(r);Byte bg = (Byte)Math.Round(g);Byte bb = (Byte)Math.Round(b);if (br > 255) br = 255;if (bg > 255) bg = 255;if (bb > 255) bb = 255;_bitmap.SetPixel(col, row, Color.FromArgb(br, bg, bb));}}t.Dispose();_bitmap.Unlock();}private Byte GetBumpMapPixel(FastBitmap bmp, Int32 x, Int32 y){if (x < 0)x = 0;if (x > _bitmap.Width - 1)x = _bitmap.Width - 1;if (y < 0)y = 0;if (y > _bitmap.Height - 1)y = _bitmap.Height - 1;return bmp.GetIntensity(x, y);}public void BumpMap(Layer bumpmap, Int32 azimuth, Int32 elevation,Int32 bevelwidth, Boolean lightzalways1){bumpmap._bitmap.Lock();_bitmap.Lock();for (Int32 row = 0; row < _bitmap.Height; row++) {for (Int32 col = 0; col < _bitmap.Width; col++) {Byte[] x = new Byte[6];x[0] = GetBumpMapPixel(bumpmap._bitmap, col - 1, row - 1);x[1] = GetBumpMapPixel(bumpmap._bitmap, col - 1, row - 0);x[2] = GetBumpMapPixel(bumpmap._bitmap, col - 1, row + 1);x[3] = GetBumpMapPixel(bumpmap._bitmap, col + 1, row - 1);x[4] = GetBumpMapPixel(bumpmap._bitmap, col + 1, row - 0);x[5] = GetBumpMapPixel(bumpmap._bitmap, col + 1, row + 1);Single normal_x = x[0] + x[1] + x[2] - x[3] - x[4] - x[5];x[0] = GetBumpMapPixel(bumpmap._bitmap, col - 1, row + 1);x[1] = GetBumpMapPixel(bumpmap._bitmap, col - 0, row + 1);x[2] = GetBumpMapPixel(bumpmap._bitmap, col + 1, row + 1);x[3] = GetBumpMapPixel(bumpmap._bitmap, col - 1, row - 1);x[4] = GetBumpMapPixel(bumpmap._bitmap, col - 0, row - 1);x[5] = GetBumpMapPixel(bumpmap._bitmap, col + 1, row - 1);Single normal_y = x[0] + x[1] + x[2] - x[3] - x[4] - x[5];Single normal_z = (6F * 255F) / bevelwidth;Single length = (Single)Math.Sqrt(normal_x * normal_x +normal_y * normal_y +normal_z * normal_z);if (length != 0) {normal_x /= length;normal_y /= length;normal_z /= length;}Double azimuth_rad = azimuth / 180.0 * Math.PI;Double elevation_rad = elevation / 180.0 * Math.PI;Single light_x = (Single)(Math.Cos(azimuth_rad) * Math.Cos(elevation_rad));Single light_y = (Single)(Math.Sin(azimuth_rad) * Math.Cos(elevation_rad));Single light_z = 1F;if (!lightzalways1)light_z = (Single)Math.Sin(elevation_rad);Single cos_light_normal = 0;cos_light_normal += normal_x * light_x;cos_light_normal += normal_y * light_y;cos_light_normal += normal_z * light_z;Color c = _bitmap.GetPixel(col, row);Single r = c.R;Single g = c.G;Single b = c.B;r *= cos_light_normal;g *= cos_light_normal;b *= cos_light_normal;Byte red = (Byte)Math.Min(Math.Round(r), 255);Byte green = (Byte)Math.Min(Math.Round(g), 255);Byte blue = (Byte)Math.Min(Math.Round(b), 255);_bitmap.SetPixel(col, row, Color.FromArgb(red, green, blue));}}_bitmap.Unlock();bumpmap._bitmap.Unlock();}
}

5 源代码 Layers.cs:

using System;
using System.Text;
using System.Collections;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;class Layers
{LayeredImage _image;ArrayList _layers = new ArrayList();public Layers(LayeredImage image){_image = image;}public Int32 Count{get { return _layers.Count; }}public Layer Add(){Layer layer = new Layer(_image.Width, _image.Height);_layers.Add(layer);return layer;}public Layer Copy(Layer layer){Layer copy = (Layer)layer.Clone();_layers.Add(copy);return copy;}public Layer this[Int32 i]{get { return (Layer)_layers[i]; }}
}

6 源代码 LayeredImage.cs:

using System;
using System.Text;
using System.Collections;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;class LayeredImage
{Int32 _width, _height;Bitmap _checkerboard;Layers _layers;public LayeredImage(Int32 width, Int32 height){_width = width;_height = height;_layers = new Layers(this);_checkerboard = new Bitmap(32, 32, PixelFormat.Format24bppRgb);Color darkgray = Color.FromArgb(102,102,102);Color lightgray = Color.FromArgb(153,153,153);for (Int32 i = 0; i < 32; i++) {for (Int32 j = 0; j < 32; j++) {if ((i < 16 && j < 16) || (i >= 16 && j >= 16))_checkerboard.SetPixel(j, i, lightgray);else_checkerboard.SetPixel(j, i, darkgray);}}Layer bglayer = _layers.Add();Graphics g = Graphics.FromImage(bglayer._bitmap._bitmap);TextureBrush brush = new TextureBrush(_checkerboard);g.FillRectangle(brush, 0, 0, _width, _height);brush.Dispose();g.Dispose();}public Int32 Width{get { return _width; }}public Int32 Height{get { return _height; }}public Layers Layers{get { return _layers; }}internal FastBitmap Flatten(){FastBitmap final = new FastBitmap(_width, _height,PixelFormat.Format24bppRgb);final.Lock();for (Int32 i = 0; i < _layers.Count; i++) {Layer l = _layers[i];l._bitmap.Lock();if (l.Mask != null)l.Mask.Lock();}for (Int32 y = 0; y < _height; y++) {for (Int32 x = 0; x < _width; x++) {Color c0 = _layers[0]._bitmap.GetPixel(x, y);for (Int32 i = 1; i < _layers.Count; i++) {Layer layer = _layers[i];Color c1 = Color.Transparent;if (x >= layer.OffsetX &&x <= layer.OffsetX + layer._bitmap.Width - 1 &&y >= layer.OffsetY &&y <= layer.OffsetY + layer._bitmap.Height - 1) {c1 = layer._bitmap.GetPixel(x - layer.OffsetX,y - layer.OffsetY);}if (c1.A == 255 && layer.Opacity == 1.0 &&layer.Mask == null) {c0 = c1;} else {Double tr, tg, tb, a;a = c1.A / 255.0 * layer.Opacity;if (layer.Mask != null) {a *= layer.Mask.GetIntensity(x, y) / 255.0;}tr = c1.R * a + c0.R * (1.0 - a);tg = c1.G * a + c0.G * (1.0 - a);tb = c1.B * a + c0.B * (1.0 - a);tr = Math.Round(tr);tg = Math.Round(tg);tb = Math.Round(tb);tr = Math.Min(tr, 255);tg = Math.Min(tg, 255);tb = Math.Min(tb, 255);c0 = Color.FromArgb((Byte)tr, (Byte)tg, (Byte)tb);}}final.SetPixel(x, y, c0);}}for (Int32 i = 0; i < _layers.Count; i++) {Layer l = _layers[i];l._bitmap.Unlock();if (l.Mask != null)l.Mask.Unlock();}final.Unlock();return final;}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/2004.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

STM32 FreeRTOS 的任务挂起与恢复以及查看任务状态

目录 任务的挂起与恢复的API函数 任务挂起函数 任务恢复函数 任务恢复函数&#xff08;中断中恢复&#xff09; 函数说明 注意事项 查看任务状态 任务的挂起与恢复的API函数 vTaskSuspend()&#xff1a;挂起任务, 类似暂停&#xff0c;可恢复 vTaskResume()&#xff1a…

vscode 扩展Cline、Continue的差别?

Cline和Continue都是VSCode的AI编程插件&#xff0c;它们在功能、用户体验、性能、适用场景以及配置和使用步骤等方面存在一些差别&#xff1a; 一、功能差异 编辑功能 Cline&#xff1a;能够分析项目的文件结构和源代码抽象语法树&#xff08;AST&#xff09;&#xff0c;通…

Unity 3D游戏开发从入门进阶到高级

本文精心整理了Unity3D游戏开发相关的学习资料&#xff0c;涵盖入门、进阶、性能优化、面试和书籍等多个维度&#xff0c;旨在为Unity开发者提供全方位、高含金量的学习指南.欢迎收藏。 学习社区 Unity3D开发者 这是一个专注于Unity引擎的开发者社区&#xff0c;汇聚了众多Un…

LLM实现视频切片合成 前沿知识调研

1.相关产品 产品链接腾讯智影https://zenvideo.qq.com/可灵https://klingai.kuaishou.com/即梦https://jimeng.jianying.com/ai-tool/home/Runwayhttps://aitools.dedao.cn/ai/runwayml-com/Descripthttps://www.descript.com/?utm_sourceai-bot.cn/Opus Cliphttps://www.opu…

1Hive概览

1Hive概览 1hive简介2hive架构3hive与Hadoop的关系4hive与传统数据库对比5hive的数据存储 1hive简介 Hive是基于Hadoop的一个数据仓库工具&#xff0c;可以将结构化的数据文件映射为一张数据库表&#xff0c;并提供类SQL查询功能。 其本质是将SQL转换为MapReduce/Spark的任务进…

IDEA的Java注释在Toggle Rendered View下的字号调整方式

记录IntelliJ IDEA的Java注释在Toggle Rendered View下的字号调整方式 如图&#xff0c;在Toggle Rendered View模式下的注释字号很大&#xff0c;与代码不协调&#xff0c;在此区域点击鼠标右键&#xff0c;选中 Adjust 出现一个滑动条&#xff0c;通过拖动游标调整字号大小…

游戏市场成果及趋势

2024 年的游戏行业发展情况如何&#xff1f;这是一个既关系到开发商&#xff0c;又关系到玩家的问题&#xff0c;而市场分析师可以为我们揭晓答案。下面&#xff0c;就让我们来看看分析师给出的结论以及他们对未来趋势的预测。 玩家 自 2021 年起&#xff0c;全球平均游戏时间…

C++复习

注&#xff1a;本文章所写内容是小编复习所看的。记录的是一些之前模糊不清的知识点。详细c内容请移步至小编主页寻找。 竞赛小技巧 竞赛中cin/cout用不了&#xff08;没有办法刷新缓冲区&#xff0c;导致cin/cout与缓冲区绑定&#xff09; 解决办法&#xff1a;(加以下三行…

【C++】多线程

目录 多线程基础什么是线程线程和进程的关系线程的特点什么是多线程编程为什么要使用多线程线程与CPU的执行关系线程的生命周期 创建线程&#xff08;C11&#xff09;线程的可调用对象传参数 注意事项join和detach的区别一个线程包含什么东西this_thread 线程同步线程同步机制互…

《深度剖析算法优化:提升效率与精度的秘诀》

想象一下&#xff0c;你面前有一堆杂乱无章的数据&#xff0c;你需要从中找到特定的信息&#xff0c;或者按照一定的规则对这些数据进行排序。又或者&#xff0c;你要为一个物流公司规划最佳的配送路线&#xff0c;以降低成本和提高效率。这些问题看似复杂&#xff0c;但都可以…

怎么实现Redis的高可用?

大家好&#xff0c;我是锋哥。今天分享关于【怎么实现Redis的高可用&#xff1f;】面试题。希望对大家有帮助&#xff1b; 怎么实现Redis的高可用&#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 为了实现 Redis 的高可用性&#xff0c;我们需要保证在发…

【CSS】HTML页面定位CSS - position 属性 relative 、absolute、fixed 、sticky

目录 relative 相对定位 absolute 绝对定位 fixed 固定定位 sticky 粘性定位 position&#xff1a;relative 、absolute、fixed 、sticky &#xff08;四选一&#xff09; top&#xff1a;距离上面的像素 bottom&#xff1a;距离底部的像素 left&#xff1a;距离左边的像素…

使用docker-compose安装Redis的主从+哨兵模式

必看 本文是一主二从一哨兵模式&#xff1b;其余的单机/集群/多哨兵模式的话&#xff0c;不在本文... 本文的环境主要是&#xff1a;应用app在本地&#xff0c;redis在云服务器上&#xff1b; 图解 图如下&#xff1a;这个图很重要&#xff1b; 之所以要这样画图&#xff0…

深度剖析RabbitMQ:从基础组件到管理页面详解

文章目录 一、简介二、Overview2.1 Overview->Totals2.2 Overview->Nodesbroker的属性2.3 Overview->Churn statistics2.4 Overview->Ports and contexts2.5 Overview->Export definitions2.6 Overview->Import definitions 三、Connections连接的属性 四、C…

[0405].第05节:搭建Redis主从架构

Redis学习大纲 一、3主3从的集群配置&#xff1a; 1.1.集群规划 1.分片集群需要的节点数量较多&#xff0c;这里我们搭建一个最小的分片集群&#xff0c;包含3个master节点&#xff0c;每个master包含一个slave节点&#xff0c;结构如下&#xff1a; 2.每组是一主一从&#x…

QT在 MacOS X上,如何检测点击程序坞中的Dock图标

最近在开发MacOS的qt应用&#xff0c;在做到最小化系统托盘功能时&#xff0c;发现关闭窗口后再次点击程序坞中的Dock图标不能将主界面再显示出来。查询里很多资料&#xff0c;发现是QT自身的问题&#xff0c;没有做相关的点击Dock图标的处理。 于是我参考了国内和国外的这两篇…

Flutter插件制作、本地/远程依赖及缓存机制深入剖析(原创-附源码)

Flutter插件在开发Flutter项目的过程中扮演着重要的角色&#xff0c;我们从 ​​​​​​https://pub.dev 上下载添加到项目中的第三方库都是以包或者插件的形式引入到代码中的&#xff0c;这些第三方工具极大的提高了开发效率。 深入的了解插件的制作、发布、工作原理和缓存机…

每日学习30分轻松掌握CursorAI:Cursor插件系统与扩展功能

Cursor插件系统与扩展功能 一、课程概述 今天我们将学习Cursor AI的插件系统&#xff0c;了解如何通过插件扩展和增强IDE功能。由于Cursor AI基于VS Code开发&#xff0c;我们可以利用丰富的VS Code插件生态系统。 1.1 学习目标 了解插件系统原理掌握插件安装管理使用常用开…

第G1周:生成对抗网络(GAN)入门

>- **&#x1f368; 本文为[&#x1f517;365天深度学习训练营]中的学习记录博客** >- **&#x1f356; 原作者&#xff1a;[K同学啊]** 本人往期文章可查阅&#xff1a; 深度学习总结 基础任务 1.了解什么是生成对抗网络2.生成对抗网络结构是怎么样的3.学习本文代码&am…

浅谈云计算03 | 云计算的技术支撑(云使能技术)

云计算的技术支撑 一、定义与内涵1.1 定义与内涵 二、云计算使能技术架构2.1 宽带网络和 Internet 架构2.2 数据中心技术2.3 虚拟化技术2.4 Web 技术2.5 多租户技术2.6 服务技术 一、定义与内涵 1.1 定义与内涵 云计算技术包含一些基础的关键技术&#xff0c;这里称为使能技术…