http://www.tongyi.net
target=_blank>http://www.tongyi.net">http://www.tongyi.net

Level:Beginner/Intermediate
Oneoftheneatfeaturesthatyoucannowleveragewith.NETistheabilitytoeasilygeneratedynamic
imagesfromcode,whichyoucantheneithersavetodiskordirectlystreambacktoabrowserclientwithASP.NET.
Thefunctionalitytogenerateimageswith.NETisencapsulatedwithintheSystem.Drawingnamespace.Itprovides
built-insupportforgeneratingimageswithanumeroffileformatsincluding:JPEG,GIF,PNG,TIFF,BMP,
PhotoCD,FlashPIX,WMF,EMFandEXIF.Notethattherearenolicenseissuestoworryaboutwithanyo
thesefileformats;Microsoftimplementationofeachformatislicensefree(includingforGIFimages).
ThegeneralmechanismthroughwhichyougeneratethesegraphicsimagesisbyconstructingaBitMapobject
whichprovidesanin-memoryrepresentationofyourimage.Youcanthencallits"Save"methodto
eithersaveittodisk,orstreamitouttoany.NEToutputstream.BecauseASP.NETexposesa.NET
OutputStreamviatheResponse.OutputStreamproperty.Thismeansyoucanstreamtheimagecontents
directlytothebrowserwithouteverhavingtosaveittodisk.
Forexample,todothisinVByouwouldwritecodelike:
'CreateIn-MemoryBitMapofJPEG
DimMyChartEngineasNewChartEngine
DimStockBitMapasBitMap=MyChartEngine.DrawChart(600,400,myChartData)
'RenderBitMapStreamBackToBrowser
StockBitMap.Save(Response.OutputStream,ImageFormat.JPEG)
IfyouareusinganASPXpagetodothis,youwillwanttomakesureyousettheappropriateHTTPContentType
headeraswell,sothatthebrowserclientdoesn'tinterpretthepage'scontentashtmlbutratherasan
image.YoucandothiseitherviasettingtheResponse.ContentTypepropertythroughcode,orviathenew
"ContentType"attributethatyoucansetonthetop-levelpagedirective:

">@PageLanguage="VB"ContentType="image/jpeg"%
NotethattheoutputcachingfeaturesofASP.NETworkforbothtextualcontentaswellasforbinaryoutput.
Assuch,ifyouaredynamicallygeneratinganimagefromapage,youcaneasilyleveragetheoutputcace
directivetoavoidhavingtoregeneratetheimageoneachrequest.Notethatimagegenerationcanbe
expensive,sothisfeatureishighlyrecommended.Forexample,thebelowdirectivecouldbeusedto
outputcachethegeneratedimagefora60secondinterval:

">@PageLanguage="VB"ContentType="image/jpeg"%

">@OutputCacheDuration="60"%
Foracompletesampleofhowtouseimagegeneration,I'veincludedasimplestockchartgenerationsample
below.Notethatthestockpricesaren'treal,justwishfulthinkingonmypart.Thesampleusesacustom
"ChartEngine"classthathelpsencapsulatethelogicrequiredtobuildupagenericchart.Youshouldbe
abletousethishelpercomponenttodoanycustomchartingofyourown,itisdefinitelynotlimited
tojuststockdata.
Feelfreetouseanyofthecodehoweveryouwantandlikewithallmyothersamples,feelfreetopost
elsewhereaswellastouseforarticles,othersamples,etc).
Instructions:
Torunthesample,copy/paste/savethebelowfilesintoanIISApplicationVRoot.Thentypete
belowstatementsintoacommandline:
mkdirbin
csc/t:library/out:bin\chartgen.dll
ChartEngine.cs/r:System.Web.dll/r:System.Winforms.dll/r:System.Drawing.dll/r:System.dll
Oncethechartenginehelperutility
iscompiled,hittheStockPicker.aspxpagetorunthesample(notethatthisinturnsetsupaimg
tagtopointtotheImageGenerator_VB.aspxpagethatdoestheactualimagegenerationwork).
StockPicker.aspx:
scriptlanguage="VB"runat=server
SubChartBtn_Click(SenderasObject,EasEventArgs)
chart.ImageUrl="ImageGenerator_Vb.aspx?"
chart.Visible=true
Fori=0toStocks.Items.Count-1
If(Stocks.Items(i).Selected=true)Then
chart.ImageUrl=chart.ImageUrl"symbols="Stocks.Items(i).Value""
EndI
Next
EndSub
/script
html
body
formrunat=server
h1Scott'sStockPicker/h1
asp:checkboxlistid="Stocks"runat=server
asp:listitemMSFT/asp:listitem
asp:listitemSUN/asp:listitem
/asp:checkboxlist
asp:buttontext="ChartYourSelectedStocks"OnClick="ChartBtn_Click"runat=server/
hr
asp:Imageid="chart"ImageUrl=""Visible=falserunat=server/
/form
/body
/html
ImageGenerator_VB.aspx:

">@PageLanguage="VB"ContentType="image/jpeg"%

">@ImportNamespace="System.Drawing"%

">@ImportNamespace="System.Drawing.Drawing2D"%

">@ImportNamespace="System.Drawing.Imaging"%

">@ImportNamespace="ChartGenerator"%

">@OutputCacheDuration="10"%
scriptlanguage="VB"runat=server
FunctionGetStockDetails(SymbolasString)asChartLine
DimmyChartLineasnewChartLine
if(symbol="msft")then
DimStockValues()asSingle={60,110,120,180,185,190,240,290}
myChartLine.Width=5
myChartLine.Color=Color.Blue
myChartLine.LineStyle=DashStyle.Solid
myChartLine.Title="MicrosoftCorp.(MSFT)"
myChartLine.Symbol="MSFT"
myChartLine.Values=StockValues
returnmyChartLine
elseif(symbol="sun")then
DimStockValues()asSingle={180,155,125,60,25,15,10,3}
myChartLine.Width=5
myChartLine.Color=Color.Red
myChartLine.LineStyle=DashStyle.Dot
myChartLine.Title="SunCorp.(Sun)"
myChartLine.Symbol="Sun"
myChartLine.Values=StockValues
returnmyChartLine
endi
returnnothing
EndFunction
SubPage_Load(SenderasObject,EasEventArgs)
'GenerateChartDataForImage....
DimXAxes()asString={"9:00AM","9:30AM","10:00AM","11:00AM","12:00AM","1:00PM","1:30PM"}
DimMyChartDataasNewChartData
MyChartData.YTickSize=20
MyChartData.YMax=250
MyChartData.YMin=0
MyChartData.XAxisTitles=XAxes
DimSymbols()asString=Request.QueryString.GetValues("symbols")
if(NotSymbols=Nothing)then
fori=0toSymbols.Length-1
DimstockValueasChartLine=GetStockDetails(symbols(i).ToLower)
If(stockValuenothing)then
myChartData.Lines.Add(stockValue)
Endi
Next
endi
'CreateIn-MemoryBitMapofJPEG
DimMyChartEngineasNewChartEngine
DimStockBitMapasBitMap=MyChartEngine.DrawChart(600,400,myChartData)
'RenderBitMapStreamBackToClient
StockBitMap.Save(Response.OutputStream,ImageFormat.JPEG)
EndSub
/script
ChartEngine.cs:
usingSystem.WinForms;
usingSystem.Collections;
usingSystem.Collections.Bases;
usingSystem.Drawing;
usingSystem.Drawing.Drawing2D;
usingSystem.Drawing.Imaging;
usingSystem.ComponentModel;
usingSystem;
usingSystem.IO;
namespaceChartGenerator{
//CoreLineDatastructure
publicstructLineData{
publicfloat[]LineValues;
publicstringLineTitle;
publicstringLineSymbol;
}
//LineDataplusdisplaystyleinformation
publicclassChartLine{
privateColorlineColor;
privateLineDatalineData;
privateDashStylelineStyle;
privateintlineWidt;
//Constructors
publicChartLine():base(){}
publicChartLine(LineDatalineData):base(){
this.lineData=lineData;
}
//Properties
publicColorColor{
get{returnlineColor;}
set{lineColor=value;}
}
publicDashStyleLineStyle{
get{returnlineStyle;}
set{lineStyle=value;}
}
publicstringSymbol{
get{returnlineData.LineSymbol;}
set{lineData.LineSymbol=value;}
}
publicstringTitle{
get{returnlineData.LineTitle;}
set{lineData.LineTitle=value;}
}
publicfloat[]Values{
get{returnlineData.LineValues;}
set{lineData.LineValues=value;}
}
publicintWidt{
get{returnlineWidth;}
set{lineWidth=value;}
}
//Methods
publicvoidSetLineData(LineDatalineData){
this.lineData=lineData;
}
}
//ChartDatastructure
publicclassChartData{
privatefloatyTickSize;
privatefloatyMax;
privatefloatyMin;
privatestring[]xAxisTitles;
privateChartLineListlines=newChartLineList();
privateColorgridColor=Color.Blue;
privateboolshowHGridLines=true;
privateboolshowVGridLines=true;
//Properties
publicfloatYTickSize{
get{returnyTickSize;}
set{yTickSize=value;}
}
publicfloatYMax{
get{returnyMax;}
set{yMax=value;}
}
publicfloatYMin{
get{returnyMin;}
set{yMin=value;}
}
publicstring[]XAxisTitles{
get{returnxAxisTitles;}
set{xAxisTitles=value;}
}
publicChartLineListLines{
get{returnlines;}
set{lines=value;}
}
publicColorGridColor{
get{returngridColor;}
set{gridColor=value;}
}
publicboolShowHGridLines{
get{returnshowHGridLines;}
set{showHGridLines=value;}
}
publicboolShowVGridLines{
get{returnshowVGridLines;}
set{showVGridLines=value;}
}
//CollectionofChartLines
publicclassChartLineList:TypedCollectionBase{
publicChartLinethis[intindex]{
get{
return(ChartLine)(List[index]);
}
set{
List[index]=value;
}
}
publicintAdd(ChartLinevalue){
returnList.Add(value);
}
publicvoidInsert(intindex,ChartLinevalue){
List.Insert(index,value);
}
publicintIndexOf(ChartLinevalue){
returnList.IndexOf(value);
}
publicboolContains(ChartLinevalue){
returnList.Contains(value);
}
publicvoidRemove(ChartLinevalue){
List.Remove(value);
}
publicvoidCopyTo(ChartLine[]array,intindex){
List.CopyTo(array,index);
}
}
}
//ChartingEngine-drawsachartbasedonthegivenChartData
publicclassChartEngine{
privateChartDatachartData;
privatefloatleft;
privatefloatright;
privatefloattop;
privatefloatbottom;
privatefloattickCount;
privatefloatyCount;
privatefloathspacing;
privatefloatvspacing;
privateGraphicsg;
privateRectangler;
privateColorbackColor;
privateColorforeColor;
privateFontbaseFont;
privateFontlegendFont;
privateRectangleFlegendRect;
publicChartEngine(){
}
publicBitmapDrawChart(intwidth,intheight,ChartDatachartData){
BitmapnewBitmap=newBitmap(width,height,PixelFormat.Format32bppARGB);
Graphicsg=Graphics.FromImage(newBitmap);
Rectangler=newRectangle(0,0,width,height);
ColormyForeColor=Color.Black;
ColormyBackColor=Color.White;
FontmyFont=newFont("Arial",10);
this.DrawChart(g,r,myBackColor,myForeColor,myFont,chartData);
returnnewBitmap;
}
publicvoidDrawChart(Graphicsg,Rectangler,ColorbackColor,ColorforeColor,FontbaseFont,ChartDatachartData){
this.chartData=chartData;
this.g=g;
this.r=r;
this.backColor=backColor;
this.foreColor=foreColor;
this.baseFont=baseFont;
this.legendFont=newFont(baseFont.FontFamily,(baseFont.Size*2/3),baseFont.Style|FontStyle.Bold);
g.SmoothingMode=SmoothingMode.AntiAlias;
CalculateChartDimensions();
DrawBackground();
InternalDrawChart();
}
privatevoidCalculateChartDimensions(){
right=r.Width-5;
top=5*baseFont.Size;
bottom=r.Height-baseFont.Size*2;
tickCount=chartData.YMin;
yCount=(chartData.YMax-chartData.YMin)/chartData.YTickSize;
hspacing=(bottom-top)/yCount;
vspacing=(right)/chartData.XAxisTitles.Lengt;
//Leftdependsonwidthoftext-forsimplicitiessakeassumethatlargestyvalueisthebiggest
//TakeintoaccountthefirstXAxistitle
floatmaxYTextSize=g.MeasureString(chartData.YMax.ToString(),baseFont).Widt;
floatfirstXTitle=g.MeasureString(chartData.XAxisTitles[0],baseFont).Widt;
left=(maxYTextSizefirstXTitle)?maxYTextSize:firstXTitle;
left=r.X+left+5;
//Calculatesizeoflegendbox
floatmaxLegendWidth=0;
floatmaxLegendHeight=0;
//Workoutsizeofbiggestlegend
foreach(ChartLineclinchartData.Lines){
floatcurrentWidth=g.MeasureString(cl.Title,legendFont).Widt;
floatcurrentHeight=g.MeasureString(cl.Title,legendFont).Height;
maxLegendWidth=(maxLegendWidthcurrentWidth)?maxLegendWidth:currentWidt;
maxLegendHeight=(maxLegendHeightcurrentHeight)?maxLegendHeight:currentHeight;
}
legendRect=newRectangleF(r.X+2,r.Y+2,maxLegendWidth+25+5,((maxLegendHeight+2)*chartData.Lines.Count)+3);
}
privatevoidDrawBackground(){
LinearGradientBrushb=newLinearGradientBrush(r,Color.SteelBlue,backColor,LinearGradientMode.Horizontal);
g.FillRectangle(b,r);
b.Dispose();
}
privatevoidInternalDrawChart(){
DrawGrid();
foreach(ChartLineclinchartData.Lines){
DrawLine(cl);
}
DrawLegend();
//Drawtimeonchart
stringtimeString="Generated:"+DateTime.Now.ToLongTimeString();
SizeFtextsize=g.MeasureString(timeString,baseFont);
g.DrawString(timeString,baseFont,newSolidBrush(foreColor),r.Width-textsize.Width-5,textsize.Height*2/3);
}
privatevoidDrawGrid(){
PengridPen=newPen(chartData.GridColor);
//Vertical-includetickdesc's
if(chartData.ShowVGridLines){
for(inti=0;(vspacing*i)right;i++){
floatx=left+(vspacing*i);
stringdesc=chartData.XAxisTitles[i];
g.DrawLine(gridPen,x,top,x,bottom+(baseFont.Size*1/3));
SizeFtextsize=g.MeasureString(desc,baseFont);
g.DrawString(desc,baseFont,newSolidBrush(chartData.GridColor),x-(textsize.Width/2),bottom+(baseFont.Size*2/3));
}
}
//Horizontal
if(chartData.ShowHGridLines){
for(floati=bottom;itop;i-=hspacing){
stringdesc=tickCount.ToString();
tickCount+=chartData.YTickSize;
g.DrawLine(gridPen,right,i,left-3,i);
SizeFtextsize=g.MeasureString(desc,baseFont);
g.DrawString(desc,baseFont,newSolidBrush(chartData.GridColor),left-textsize.Width-3,i-(textsize.Height/2));
}
}
}
privatevoidDrawLine(ChartLinechartLine){
PenlinePen=newPen(chartLine.Color);
linePen.StartCap=LineCap.Round;
linePen.EndCap=LineCap.Round;
linePen.Width=chartLine.Widt;
linePen.DashStyle=chartLine.LineStyle;
PointF[]Values=newPointF[chartLine.Values.Length];
floatscale=hspacing/chartData.YTickSize;
for(inti=0;ichartLine.Values.Length;i++){
floatx=left+vspacing*i;
Values[i]=newPointF(x,bottom-chartLine.Values[i]*scale);
}
g.DrawLines(linePen,Values);
}
privatevoidDrawLegend(){
//DrawLegendBox
ControlPaint.DrawBorder(g,(Rectangle)legendRect,SystemColors.WindowFrame,ButtonBorderStyle.Solid);
LinearGradientBrushb=newLinearGradientBrush(legendRect,backColor,Color.SteelBlue,LinearGradientMode.Horizontal);
r.Inflate(-1,-1);
g.FillRectangle(b,legendRect);
b.Dispose();
floatstartY=5;
foreach(ChartLineclinchartData.Lines){
Penp=newPen(cl.Color);
p.Width=p.Width*4;
SizeFtextsize=g.MeasureString(cl.Title,legendFont);
floatlineY=startY+textsize.Height/2;
g.DrawLine(p,r.X+7,lineY,r.X+25,lineY);
g.DrawString(cl.Title,legendFont,newSolidBrush(foreColor),r.X+30,startY);
startY+=(textsize.Height+2);
}
}
}
}

創作者介紹
創作者 shadow 的頭像
shadow

資訊園

shadow 發表在 痞客邦 留言(0) 人氣()