WPF+WriteableBitmap實現(xiàn)高性能曲線圖的繪制_第1頁
WPF+WriteableBitmap實現(xiàn)高性能曲線圖的繪制_第2頁
WPF+WriteableBitmap實現(xiàn)高性能曲線圖的繪制_第3頁
WPF+WriteableBitmap實現(xiàn)高性能曲線圖的繪制_第4頁
WPF+WriteableBitmap實現(xiàn)高性能曲線圖的繪制_第5頁
已閱讀5頁,還剩10頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

第WPF+WriteableBitmap實現(xiàn)高性能曲線圖的繪制目錄一、前言二、正文三、運(yùn)行效果

一、前言

之前分享過一期關(guān)于DrawingVisual來繪制高性能曲線的博客,今天再分享一篇通過另一種方式來繪制高性能曲線的方法,也就是通過WriteableBitmap的方式;具體的一些細(xì)節(jié)這里就不啰嗦了,同樣是局部繪制的思想,滾動條拖動到哪里,就只繪制那一部分的曲線,直接貼代碼;(該程序在英特爾11代CPU的電腦可能會遇到拖動滾動條曲線圖卡住不動的情況,這個是顯卡驅(qū)動的問題,官方已經(jīng)修復(fù)了,遇到這問題的記得更新一下驅(qū)動)

二、正文

1、新建一個類,繼承FrameworkElement,然后在里面實現(xiàn)一下繪圖的邏輯;

usingSystem;

usingSystem.Collections.Generic;

usingSystem.Drawing;

usingSystem.Drawing.Drawing2D;

usingSystem.Drawing.Text;

usingSystem.IO;

usingSystem.Windows;

usingSystem.Windows.Media;

usingSystem.Windows.Media.Imaging;

usingSystem.Windows.Resources;

using_Font=System.Drawing.Font;

usingGDI=System.Drawing;

namespaceWriteableBitmapDemo.Controls

publicclassCruveWriteableBitmap:FrameworkElement

privatestaticPrivateFontCollectionpfc=newPrivateFontCollection();

privateWriteableBitmapbitmap;

privateintbitmap_width=0;

privateintbitmap_height=0;

privatestatic_Fontfont=null;

privatestatic_Fonttime_font=null;

privatePointF[][]horizontals=null;

privatePointF[][]horizontals_thin=null;

privatePointF[][]verticals=null;

privatePointF[][]verticals_thin=null;

privateListPointFtop_points1;

privateListPointFtop_points2;

privateListPointFtop_points3;

privateListPointFbottom_points;

privateListPointFlabelPosition_up;

privateListstringlabelText_up;

privateListPointFlabelPosition_down;

privateListstringlabelText_down;

privateListPointFtimePosition;

privateListstringtimeText;

privateGDI.PenblackPen=newGDI.Pen(GDI.Color.Black,1.5f);

privateGDI.PengrayPen=newGDI.Pen(GDI.Color.Gray,1f);

privateGDI.Pentop_pen1=newGDI.Pen(GDI.Color.Black,2);

privateGDI.Pentop_pen2=newGDI.Pen(GDI.Color.Orange,2);

privateGDI.Pentop_pen3=newGDI.Pen(GDI.Color.Purple,2);publicfloatscaleX{get;set;}=1f;

privatefloat_ScaleY{get;set;}=1f;

publicfloatScaleY

get{return_ScaleY;}

_ScaleY=value;

staticCruveWriteableBitmap()

varappRootDataDir=Path.Combine(AppDomain.CurrentDomain.BaseDirectory,"msyh.ttf");

if(!File.Exists(appRootDataDir))

varkey=$"/CurveChartDemo;component/Fonts/msyh.ttf";

StreamResourceInfoinfo=Application.GetResourceStream(newUri(key,UriKind.Relative));

using(varstream=info.Stream)

byte[]bytes=newbyte[stream.Length];

intlen=stream.Read(bytes,0,bytes.Length);

File.WriteAllBytes(appRootDataDir,bytes);

pfc.AddFontFile(appRootDataDir);

publicCruveWriteableBitmap()

time_font=new_Font(pfc.Families[0],10);

font=new_Font(pfc.Families[0],8);

publicvoidDrawPoints()

//InitBitmap();

if(this.bitmap==null)

return;

this.bitmap.Lock();

using(BitmapbackBufferBitmap=newBitmap(this.bitmap_width,this.bitmap_height,

this.bitmap.BackBufferStride,GDI.Imaging.PixelFormat.Format24bppRgb,

this.bitmap.BackBuffer))

using(GraphicsbackBufferGraphics=Graphics.FromImage(backBufferBitmap))

backBufferGraphics.SmoothingMode=SmoothingMode.AntiAlias;

backBufferGraphics.CompositingQuality=CompositingQuality.HighSpeed;

backBufferGraphics.Clear(GDI.Color.White);

//粗橫線

if(this.horizontals!=null)

foreach(varhorizontalinthis.horizontals)

backBufferGraphics.DrawLine(blackPen,horizontal[0],horizontal[1]);

//細(xì)橫線

if(this.horizontals_thin!=null)

foreach(varhorizontalinthis.horizontals_thin)

backBufferGraphics.DrawLine(grayPen,horizontal[0],horizontal[1]);

//粗豎線

if(this.verticals!=null)

foreach(varverticalinthis.verticals)

backBufferGraphics.DrawLine(blackPen,vertical[0],vertical[1]);

//細(xì)豎線

if(this.verticals_thin!=null)

foreach(varverticalinthis.verticals_thin)

backBufferGraphics.DrawLine(grayPen,vertical[0],vertical[1]);

//上圖曲線1

if(this.top_points1!=nullthis.top_points1.Count0)

backBufferGraphics.DrawLines(top_pen1,top_points1.ToArray());

//上圖曲線2

if(this.top_points2!=nullthis.top_points2.Count0)

backBufferGraphics.DrawLines(top_pen2,this.top_points2.ToArray());

//上圖曲線3

if(this.top_points3!=nullthis.top_points3.Count0)

backBufferGraphics.DrawLines(top_pen3,this.top_points3.ToArray());

//下圖曲線

if(this.bottom_points!=nullthis.bottom_points.Count0)

backBufferGraphics.DrawLines(top_pen1,this.bottom_points.ToArray());

//文本

if(labelPosition_up!=nulllabelPosition_up.Count0)

SizeFfontSize=backBufferGraphics.MeasureString(labelText_up[0],font);

for(inti=0;ilabelPosition_up.Count;++i)

backBufferGraphics.DrawString(labelText_up[i],font,GDI.Brushes.Black,labelPosition_up[i].X,labelPosition_up[i].Y-fontSize.Height);

if(labelPosition_down!=nulllabelPosition_down.Count0)

for(inti=0;ilabelPosition_down.Count;++i)

backBufferGraphics.DrawString(labelText_down[i],font,GDI.Brushes.Black,labelPosition_down[i].X,labelPosition_down[i].Y);

if(timePosition!=nulltimePosition.Count0)

for(inti=0;itimePosition.Count;++i)

if(i==0)

backBufferGraphics.DrawString(timeText[i],time_font,GDI.Brushes.Black,timePosition[i].X,timePosition[i].Y);

else

SizeFfontSize=backBufferGraphics.MeasureString(timeText[i],time_font);

backBufferGraphics.DrawString(timeText[i],time_font,GDI.Brushes.Black,timePosition[i].X-fontSize.Width/2,timePosition[i].Y);

backBufferGraphics.Flush();

this.bitmap.AddDirtyRect(newInt32Rect(0,0,this.bitmap_width,this.bitmap_height));

this.bitmap.Unlock();

}publicvoidUpdateTimeLabel(ListPointFtimePosition,ListstringtimeText)

this.timePosition=timePosition;

this.timeText=timeText;

publicvoidUpdatePosition(ListPointFfhr1_points,ListPointFfhr2_points,ListPointFfhr3_points,ListPointFtoco_points)

this.top_points1=fhr1_points;

this.top_points2=fhr2_points;

this.top_points3=fhr3_points;

this.bottom_points=toco_points;

publicvoidUpdateLabelPosition(ListPointFlabelPosition_up,ListstringlabelText_up,ListPointFlabelPosition_down,ListstringlabelText_down)

this.labelPosition_up=labelPosition_up;

this.labelText_up=labelText_up;

this.labelPosition_down=labelPosition_down;

this.labelText_down=labelText_down;

publicvoidUpdateHorizontalLine(PointF[][]horizontals,PointF[][]horizontals_thin)

this.horizontals=horizontals;

this.horizontals_thin=horizontals_thin;

publicvoidUpdateVerticalLine(PointF[][]verticals,PointF[][]verticals_thin)

this.verticals=verticals;

this.verticals_thin=verticals_thin;

protectedoverridevoidOnRender(DrawingContextdc)

InitBitmap();

if(this.bitmap!=null)

dc.DrawImage(bitmap,newRect(0,0,RenderSize.Width,RenderSize.Height));

base.OnRender(dc);

privatevoidInitBitmap()

if(bitmap==null||this.bitmap.Width!=(int)this.ActualWidth||this.bitmap.Height!=(int)this.ActualHeight)

if((int)this.ActualWidth0(int)this.ActualHeight0)

this.bitmap_width=(int)this.ActualWidth;

this.bitmap_height=(int)this.ActualHeight;

this.bitmap=newWriteableBitmap(bitmap_width,bitmap_height,96,96,PixelFormats.Bgr24,null);

this.bitmap.Lock();

using(BitmapbackBufferBitmap=newBitmap(bitmap_width,bitmap_height,

this.bitmap.BackBufferStride,GDI.Imaging.PixelFormat.Format24bppRgb,

this.bitmap.BackBuffer))

using(GraphicsbackBufferGraphics=Graphics.FromImage(backBufferBitmap))

backBufferGraphics.SmoothingMode=SmoothingMode.HighSpeed;

backBufferGraphics.CompositingQuality=CompositingQuality.HighSpeed;

backBufferGraphics.Clear(GDI.Color.White);

backBufferGraphics.Flush();

this.bitmap.AddDirtyRect(newInt32Rect(0,0,bitmap_width,bitmap_height));

this.bitmap.Unlock();

}

2、主窗口添加該控件,并添加滾動條那些

Window

x:xmlns="/winfx/2006/xaml/presentation"

xmlns:x="/winfx/2006/xaml"

xmlns:ct="clr-namespace:WriteableBitmapDemo.Controls"

xmlns:d="/expression/blend/2008"

xmlns:local="clr-namespace:WriteableBitmapDemo"

xmlns:mc="/markup-compatibility/2006"

Title="MainWindow"

Width="1500"

Height="450"

Loaded="Window_Loaded"

mc:Ignorable="d"

Grid

ct:CruveWriteableBitmapx:Name="curve"Margin="0,0,0,20"/

ScrollViewer

Name="scroll"

HorizontalScrollBarVisibility="Auto"

ScrollChanged="ScrollViewer_ScrollChanged"

VerticalScrollBarVisibility="Disabled"

Canvasx:Name="canvas"Height="1"/

/ScrollViewer

Canvas

x:Name="CanvasPanel"

Margin="0,0,0,20"

Background="Transparent"/

/Grid

/Window

3、主窗口后臺添加曲線數(shù)值生成方法和更新視圖數(shù)據(jù)方法

usingSystem.Collections.Generic;

usingSystem.Drawing;

usingSystem.Windows;

usingSystem.Windows.Controls;

usingSystem.Windows.Input;

namespaceWriteableBitmapDemo

///summary

///MainWindow.xaml的交互邏輯

////summary

publicpartialclassMainWindow:Window

privateboolisAdd=true;

privateDictionaryint,intdicTopPoints=newDictionaryint,int

privateDictionaryint,intdicBottomPoints=newDictionaryint,int

privatefloaty_scale;

privatestaticintTop_Val_Max=240;

privatestaticintTop_Val_Min=30;

privatestaticintTop_X_Sex=20;

privatestaticintBottom=100;

privatestaticintCenter=25;

privatestaticintBottomOffset=0;

privatedoubleoffset=-1;

publicMainWindow()

InitializeComponent();

CanvasPanel.MouseMove+=delegate(objectsender,MouseEventArgse)

if(e.LeftButton==MouseButtonState.Pressed)

if(Mouse.Captured==null)Mouse.Capture(CanvasPanel);

if(offset=0offset=CanvasPanel.ActualWidth)

scroll.ScrollToHorizontalOffset(scroll.HorizontalOffset-(e.GetPosition(this).X-offset));

offset=e.GetPosition(this).X;

else

offset=-1;

Mouse.Capture(null);//釋放鼠標(biāo)捕獲

privatevoidWindow_Loaded(objectsender,RoutedEventArgse)

//生成曲線數(shù)據(jù)

inttemp=50;

for(inti=0;i24*60*60*4;i++)

if(isAdd)

dicTopPoints.Add(i,temp);

temp+=2;

else

dicTopPoints.Add(i,temp);

temp-=2;

if(temp==210)isAdd=false;

if(temp==50)isAdd=true;

temp=0;

for(inti=0;i24*60*60*4;i++)

if(isAdd)

dicBottomPoints.Add(i,temp);

temp+=2;

else

dicBottomPoints.Add(i,temp);

temp-=2;

if(temp==100)isAdd=false;

if(temp==0)isAdd=true;

//初始化滾動條和觸發(fā)曲線繪制

canvas.Width=dicTopPoints.Count;

scroll.ScrollToLeftEnd();

privatevoidScrollViewer_ScrollChanged(objectsender,ScrollChangedEventArgse)

InitChartData((float)scroll.HorizontalOffset);

///summary

///根據(jù)滾動條偏移量更新需要繪制的數(shù)據(jù)

////summary

///paramname="offset"/param

privatevoidInitChartData(floatoffset)

y_scale=(float)((curve.ActualHeight-Center)/(Top_Val_Max-Top_Val_Min+Bottom));

//上圖橫線

ListPointF[]horizontalList=newListPointF[]

ListPointF[]horizontalList_thin=newListPointF[]

for(inty=0;y=Top_Val_Max-Top_Val_Min;y+=10)

floatcurrentHeight=(float)(curve.ActualHeight-(y+Bottom)*y_scale-Center);

PointFpoint1=newPointF(0,currentHeight);

PointFpoint2=newPointF((float)curve.ActualWidth,currentHeight);

if(y%30==0)

horizontalList.Add(newPointF[]{point1,point2});

else

horizontalList_thin.Add(newPointF[]{point1,point2});

for(inty=0;y=Bottom;y+=10)

floatcurrentHeight=(float)(curve.ActualHeight-y*y_scale-BottomOffset);

PointFpoint1=newPointF(0,currentHeight);

PointFpoint2=newPointF((float)curve.ActualWidth,currentHeight);

if(y%20==0)

horizontalList.Add(newPointF[]{point1,point2});

else

horizontalList_thin.Add(newPointF[]{point1,point2});

//豎線與文字

ListPointF[]verticals=newListPointF[]

ListPointF[]verticals_thin=newListPointF[]

ListPointFtimePosition=newListPointF

ListstringtimeText=newListstring

ListPointFlabelPosition_up=newListPointF

ListstringlabelText_up=newListstring

ListPointFlabelPosition_down=newListPointF

ListstringlabelText_down=newListstring

for(inti=0;ioffset+curve.ActualWidth;i+=Top_X_Sex*2)

if(ioffset)continue;

//下豎線

PointFpoint1=newPointF(i-offset,(float)(curve.ActualHeight-BottomOffset));

PointFpoint2=newPointF(i-offset,(float)(curve.ActualHeight-Bottom*y_scale-BottomOffset));

//上豎線

PointFpoint3=newPointF(i-offset,0);

PointFpoint4=newPointF(i-offset,(float)(curve.ActualHeight-Bottom*y_scale-Center));

if((i+(60*2))%(60*2)==0)

verticals.Add(newPointF[]{point1,point2});

verticals.Add(newPointF[]{point3,point4});

else

verticals_thin.Add(newPointF[]{point1,point2});

verticals_thin.Add(newPointF[]{point3,point4});

if(i%240==0)

timeText.Add(i+"");

timePosition.Add(newPointF(i-offset,(float)(curve.ActualHeight-Bottom*y_scale-Center)));

if((i+(60*2))%(120*2)==0)

for(inty=Top_Val_Min;y=Top_Val_Max;y+=10)

if(y%30==0)

labelText_up.Add(y+"");

labelPosition_up.Add(newPointF(i-offset,(float)(curve.ActualHeight-(Bottom+y-Top_Val_Min)*y_scale-Center)));

for(inty=20;y=100;y+=10)

if(y%20==0)

labelText_down.Add(y+"");

labelPosition_down.Add(newPointF(i-offset,(float)(curve.ActualHeight-y*y_scale)));

ListPointFtop_points1=newListPointF

for(int

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論