【 Silverlight】Bitmap 位图和Particle引擎

24位BMP图像处理与流数据分析
本文介绍了一种处理24位位图(BMP)文件的方法,包括读取文件、解析图像数据并计算10x10像素区域的平均颜色值。通过使用C#语言实现了一个具体的应用实例,展示了如何利用这些技术进行图像处理。

毋庸置疑又是繁忙的一年过去了,在这一年中我的项目BLUR BLUR BLUR以致于我到现在才有时间发表一篇新的BLOG,不过放心,十年不鸣,一鸣惊人。我带给你的总是业界最新的技术

首先也是首要的我们今天要讨论流数据和颗粒,下面是部分的代码:

注意: 上传任何的24位位图所有的二进制流都在客户端处理,所以服务端不需要任何的处理



这里的主循环用来从客户端的对话框中取出一个位图,然后将其解重要信息解析到客户端的一个数组,然后保存那些重要的图像颜色信息

[...]
usingSystem.Windows.Media.Imaging;
usingSystem.IO;
usingSystem.Windows.Browser;
usingSystem.Windows.Resources;

drawSqaure[]tiles;
doubletotalCol=0;
doubletotalRow=0;
doubleimageWidth=0;
doubleimageHeight=0;

[...]

privatevoidOpenBMP()
...{
OpenFileDialogofd
=newOpenFileDialog();

if(ofd.ShowDialog()==DialogResult.OK)
...{
Streamstream
=ofd.SelectedFile.OpenRead();
output
=ofd.SelectedFile.Name;


//Findouthowbigthefileis.CreateaBytearraytoholdit.
//ReadthevaluesyouneedfromtheBitmapdatastream...

intnBytes=Convert.ToInt32(stream.Length);
byte[]ByteArray=newbyte[nBytes];
intnBytesRead=stream.Read(ByteArray,0,nBytes);
stream.Close();


//BMPHeaderfilesstartwithBandMinAscii
//
通过文件头的信息来判断文件的类型

if((ByteArray[0]==66)&&(ByteArray[1]==77))
...{
output
+="[24bitBMPFile]";
}

else
...{
output
="ERROR:FileisnotaBMP";
txtOut.Text
=output;
return;
}


//BMPfileswillpadthestreamwithleadingzerosifthe
//imagewidthinpixelsisnotdivisbleby4

imageWidth
=(double)(convert4Bytes(ByteArray[18],ByteArray[19],
ByteArray[
20],ByteArray[21]));
doublerowPad=imageWidth%4;
imageHeight
=(double)(convert4Bytes(ByteArray[22],ByteArray[23],
ByteArray[
24],ByteArray[25]));
intdataOffset=convert4Bytes(ByteArray[10],ByteArray[11],
ByteArray[
12],ByteArray[13]);
intbitDepth=convert2Bytes(ByteArray[28],ByteArray[29]);
intimageDataSize=convert4Bytes(ByteArray[34],ByteArray[35],
ByteArray[
36],ByteArray[37]);

if((imageWidth>600)||(imageHeight>600))...{
output
="ERROR:Imagetoolarge.Pleaseselectanotherfile.";
txtOut.Text
=output;
return;
}


if(bitDepth!=24)
...{
output
+="ERROR:Colordepthmustbesetat24bits.";
txtOut.Text
=output;
return;
}



//Iwillbecalculatingoutthecoloraverageof10x10pixel
//squaresfromtheimageandstoringtheminadrawSqaureobject.
//A24bitBMPuses3bytesperpixelforthecolor.Thiscode
//caneasilybeexpandedtosupportotherbitdepthsaswell.

intresolution=10;
intbytesPerPixel=3;

totalCol
=Math.Floor(imageWidth/resolution);
totalRow
=Math.Floor(imageHeight/resolution);

inttotalTiles=(int)(totalCol*totalRow);
tiles
=newdrawSqaure[totalTiles];

doublerowOffset=0;
doublepointer=0;
intindex=0;


//Hereistheimportantpart.IhavenowstoredtheBitmap
//image'sstreaminmybytearrayandIhavecreatedanarray
//of'drawSquare'objectstobepopulatedwiththeaverage
//ofthe10x10pixelsquarecolorvaluesIwillnextcalculate.


for(intr=0;r<totalRow;r++)
...{

//BMPfilessendtheirpixeldatafromthebottomleftcorner
//oftheimageUP.Also,whiletheirpixeldataistraditional
//0-255perRGBcolor,theORDERisreversed,soitcomesin
//BGR,notRGB.

rowOffset
=54+(r*(resolution*
((imageWidth
*bytesPerPixel)+rowPad)));
for(intc=0;c<totalCol;c++)
...{
pointer
=rowOffset+(c*resolution*bytesPerPixel);
drawSqaured
=newdrawSqaure();
intb=0;
intg=0;
intred=0;

for(inti=0;i<resolution;i++)
...{
for(inty=0;y<resolution;y++)
...{
intcalc=Convert.ToInt32(pointer+
(i
*((imageWidth*bytesPerPixel)+rowPad))+(y*3));
b
+=(int)ByteArray[calc];
g
+=(int)ByteArray[calc+1];
red
+=(int)ByteArray[calc+2];
}

}


//Sincetheabovenestedforloopswillsamplea10x10pixel
//square,IneedtodividethesumofeachColorby100to
//getitscoloraverageperchannel.

d.red
=red/100;
d.blue
=b/100;
d.green
=g/100;
tiles[index]
=d;
index
++;
}

}

txtOut.Text
=output;
ByteArray
=null;
buildUI();
}

}


drawSquare 对象保存的是每个画布TILE将添加到屏幕的颜色的平均值:
publicclassdrawSqaure
...{
publicintred...{get;set;}
publicintblue...{get;set;}
publicintgreen...{get;set;}

}


下面是一个创建UI的主循环

privatevoidbuildUI()
...{
intindex=0;
intnodeSize=2;
nodes.Children.Clear();

for(intr=0;r<totalRow;r++)
...{
for(intc=0;c<totalCol;c++)
...{
noden
=newnode();
n.SetValue(NameProperty,
"n_"+c.ToString()+"_"+r.ToString());
n.X
=origin.X-(totalCol*(nodeSize*.5))+(c*nodeSize);
n.Y
=origin.Y-30+(totalRow*(nodeSize*.5))-(r*nodeSize);
n.anchor
=newPoint(n.X,n.Y);
n.vX
=0;
n.vY
=0;
drawSqaured
=tiles[index];
index
++;
n.setColor(Color.FromArgb(
0xFF,Convert.ToByte(d.red),
Convert.ToByte(d.green),Convert.ToByte(d.blue)));
nodes.Children.Add(n);
}

}


index
=0;
tiles
=null;
}


privateInt32convert4Bytes(bytea,byteb,bytec,byted)
...{return((d<<24)|(c<<16)|(b<<8)|(a));}

privateInt32convert2Bytes(bytea,byteb)
...{return((b<<8)|(a));}


用户控制节点是空的,我们可以通过setColor()设置2×2的矩形的颜色,或者通过X,Y属性,正如我前面无数次提到的那样

最后的动画看起来就是这样的:

 
voidsb_Completed(objectsender,EventArgse)
...{
foreach(nodeninnodes.Children)
...{
n.vX
+=((double)r.Next(100)-50.0)/5.0;
n.vY
+=((double)r.Next(100)-50.0)/5.0;
n.vX
*=buzz;
n.vY
*=buzz;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值