65.9K
CodeProject 正在变化。 阅读更多。
Home

Silverlight 中的像素操作

starIconstarIconstarIconstarIconstarIcon

5.00/5 (6投票s)

2012 年 2 月 3 日

CPOL

3分钟阅读

viewsIcon

27574

downloadIcon

1006

Silverlight 中的像素操作

引言

本文解释了如何操作图像的单个像素以实现一些图像处理功能。 使用这些技术,可以轻松开发/增强诸如图像亮度调整、图像对比度更改、应用伽马校正、图像着色等功能...

背景

读者必须对 Silverlight 及其相关控件有一定程度的熟悉。

Using the Code

该应用程序由一个主页面组成,该页面为每个图像处理例程提供一个滑块。 MouseLeftButtonUp 事件后面的代码执行上述功能。 代码是用 C# 在 Visual Studio 2010 Express Edition 中开发的。

关于初始化的一些说明

为了获取图像的单个像素,应用程序首先支持一个 Silverlight 图像控件,其源设置为相对路径(即 Images/2.jpg)。 加载图像后,将创建一个 WriteableBitmap 对象,如下所示。

         wbOriginal = new WriteableBitmap((UIElement)sender,null);

注意: Sender 是一个图像控件。

WriteableBitmap 对象也可以从 BitmapImage 对象构造,这在代码中已经完成。 将图像加载到 BitmapImage 对象中非常简单。 加载到 BitmapImage 对象后,您只需要将 Image Silverlight 控件的 source 属性分配给这个 BitmapImage 对象。 每当 Image 控件的 source 发生变化时,关联的 WriteableBitmap 对象就会自动更新为新的 Image。

让我们从改变亮度功能开始。

亮度

改变亮度只是将一个固定数字(<255)添加到图像的各个像素中。 首先,创建关联 WriteableBitmap 对象的临时副本,并将各个像素的红色、绿色和蓝色颜色提取到像素中,如下所示

int pixel = wb.Pixel[i];
int B = (int)(pixel & 0xFF); pixel >>= 8;
int G = (int)(pixel & 0xFF); pixel >>= 8;
int R = (int)(pixel & 0xFF); pixel >>= 8;
int A = (int)(pixel);

每个像素由一个 32 位整数表示,其中蓝色、绿色、红色占据像素中的第一、第二和第三个位置。 红色、绿色和蓝色中的每一个都可以取一个从 0 到 255 的值,更确切地说,是一个字节值,位于 int 像素变量内。

亮度的量由亮度滑块相对于其先前位置移动的距离决定。 将该值添加到每个像素的 R、G、B,并将其归一化为 255,如下所示。

B += (int)sliderBrightness.Value; 
R += (int)sliderBrightness.Value; 
G += int)sliderBrightness.Value;
if (R > 255) R = 255; if (G > 255) G = 255; if (B > 255) B = 255;
if (R < 0) R = 0; if (G < 0) G = 0; if (B < 0) B = 0;

现在完成了,是时候将这些值放回 wb(新的 WriteableBitmap 对象)中,然后再放回 Silverlight 图像控件中。

wb.Pixels[i] = B | (G << 8) | (R << 16) | (A << 24);
wb.Invalidate();
image1.Source = wb;

让我们继续另一个图像处理例程,即幂律。

幂律

获取各个像素的基础知识保持不变。 幂律实际上使图像的暗区域变暗,并使图像的亮区域变亮。 为此,幂律首先定义一个双精度数组

double[] dPowerLawFactorArray = { .6, 1.7, .8, .9, 1.02, 1.03, 1.05, 1.07, 1.09, 1.1};

根据幂律滑块的移动,从该数组中选择一个值并应用于各个像素的 R、G 和 B 值,如下所示。

//nIndex corresponds to the current Power law slider position
double dPowerlawfactor = dPowerLawFactorArray[nIndex]; 
R = (int)Math.Pow(R, dPowerlawfactor);
G = (int)Math.Pow(G, dPowerlawfactor);
B = (int)Math.Pow(B, dPowerlawfactor);

改变图像的对比度

double[] contrastArray = { 1, 1.2, 1.3, 1.6, 1.7, 1.9, 2.1, 2.4, 2.6, 2.9 };
//nIndex corresponds to the current Contrats slider position
double CFactor = contrastArray[nIndex]; 
R = (int) Math.Max(0, Math.Min(255, (((R - 128) * CFactor) + 128)));
G = (int)Math.Max(0, Math.Min(255, (((G - 128) * CFactor) + 128)));
B = (int)Math.Max(0, Math.Min(255, (((B - 128) * CFactor) + 128)));

伽马方程

double[] dGammaArray = new double[19];

dGammaArray[0] = .1;
dGammaArray[1] = .2;
dGammaArray[2] = .3;
dGammaArray[3] = .4;
dGammaArray[4] = .5;
dGammaArray[5] = .6;
dGammaArray[6] = .7;
dGammaArray[7] = .8;
dGammaArray[8] = .9;
dGammaArray[9] = 1;
dGammaArray[10] = 1.1;
dGammaArray[11] = 1.2;
dGammaArray[12]=1.3;
dGammaArray[13]=1.4;
dGammaArray[14] = 1.5;
dGammaArray[15] = 1.6;
dGammaArray[16] = 1.7;
dGammaArray[17] = 1.8;
dGammaArray[18] = 1.9;

//nIndex corresponds to the current Gamma slider position
double dGamma = dGammaArray[nIndex];

double dDinvgamma = 1.0 / dGamma;

double dMax = Math.Pow(255.0, dDinvgamma) / 255.0;

R = (int)Math.Max(0, Math.Min(255, (Math.Pow(R, dDinvgamma) / dMax)));
G = (int)Math.Max(0, Math.Min(255, (Math.Pow(G, dDinvgamma) / dMax)));
B = (int)Math.Max(0, Math.Min(255, (Math.Pow(B, dDinvgamma) / dMax)));

为图像着色

在此,用户首先借助给定的滑块设置要应用于所选图像的蓝色、红色、绿色的量。 一旦做出选择,就可以单击“颜色图像”按钮。 此功能将所选颜色应用于图像,如下所示

R += (int)sliderRedNess.Value; 
G += (int)sliderGreenNess.Value;
B += (int)sliderBlueNess.Value;

灰度

这只是应用于每个像素的 R、G、B 值的平均值

R = G = B = (R + G + B) / 3;

为了使应用程序更有趣,将一些 StoryBoard 动画和缓动函数应用于图像控件。 此动画在图像稳定到正常视图之前,在 X、Y 和 Z 轴上旋转图像。

© . All rights reserved.