




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第WPF+WriteableBitmap實(shí)現(xiàn)高性能曲線圖的繪制目錄一、前言二、正文三、運(yùn)行效果
一、前言
之前分享過(guò)一期關(guān)于DrawingVisual來(lái)繪制高性能曲線的博客,今天再分享一篇通過(guò)另一種方式來(lái)繪制高性能曲線的方法,也就是通過(guò)WriteableBitmap的方式;具體的一些細(xì)節(jié)這里就不啰嗦了,同樣是局部繪制的思想,滾動(dòng)條拖動(dòng)到哪里,就只繪制那一部分的曲線,直接貼代碼;(該程序在英特爾11代CPU的電腦可能會(huì)遇到拖動(dòng)滾動(dòng)條曲線圖卡住不動(dòng)的情況,這個(gè)是顯卡驅(qū)動(dòng)的問(wèn)題,官方已經(jīng)修復(fù)了,遇到這問(wèn)題的記得更新一下驅(qū)動(dòng))
二、正文
1、新建一個(gè)類(lèi),繼承FrameworkElement,然后在里面實(shí)現(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、主窗口添加該控件,并添加滾動(dòng)條那些
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、主窗口后臺(tái)添加曲線數(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;
//初始化滾動(dòng)條和觸發(fā)曲線繪制
canvas.Width=dicTopPoints.Count;
scroll.ScrollToLeftEnd();
privatevoidScrollViewer_ScrollChanged(objectsender,ScrollChangedEventArgse)
InitChartData((float)scroll.HorizontalOffset);
///summary
///根據(jù)滾動(dòng)條偏移量更新需要繪制的數(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. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年銀行文明服務(wù)試題及答案
- 2025年銀行審計(jì)考試題庫(kù)及答案
- 2025年銀行審計(jì)筆試題及答案
- 2025年專(zhuān)升本概率論試題及答案
- 2025年專(zhuān)升本會(huì)計(jì)考試題庫(kù)答案
- 2025年專(zhuān)利實(shí)務(wù) 試題及答案
- 2026屆四川省成都市高新南區(qū)重點(diǎn)名校中考數(shù)學(xué)考試模擬沖刺卷含解析
- 平武縣任家壩110千伏變電站增容改造輸變電工程環(huán)評(píng)報(bào)告
- 2025中國(guó)鋁業(yè)股份有限公司招聘11人筆試參考題庫(kù)附帶答案詳解(10套)
- 2025年度安徽宣城市保安服務(wù)有限公司第五次招聘5人筆試參考題庫(kù)附帶答案詳解(10套)
- 提高軟化器周期制水量壓制
- 特種設(shè)備安全管理-使用知識(shí)
- 難治性高血壓的治療策略
- 肝臟腫瘤的影像診斷及鑒別診斷講座演示文稿
- 2023年全科醫(yī)師轉(zhuǎn)崗培訓(xùn)理論考試試題及答案
- GB/T 17642-1998土工合成材料非織造復(fù)合土工膜
- 3C認(rèn)證全套體系文件(手冊(cè)+程序文件)
- 魚(yú)類(lèi)繁殖與發(fā)育課件
- (完整)五金材料采購(gòu)清單
- 政企業(yè)務(wù)認(rèn)知題庫(kù)V1
- 制造執(zhí)行系統(tǒng)的功能與實(shí)踐最新ppt課件(完整版)
評(píng)論
0/150
提交評(píng)論