2012-01-17 157 views
2

我在自定義FrameworkElement的OnRender方法中繪製圖像。我也想畫出這張照片的影子。我需要在代碼中這樣做,並且我不想使用DropShadowBitmapEffect,因爲它已經過時。我怎樣才能做到這一點?在DrawingContext上繪圖時在圖像上繪製陰影

public class MyDrawingView : FrameworkElement 
    { 
     protected override void OnRender(System.Windows.Media.DrawingContext dc) 
     { 
      drawImagesOnDrawingContext(dc); 
     } 

     public RenderTargetBitmap getBitmap() 
     { 
      DrawingVisual dv = new DrawingVisual(); 
      using (DrawingContext dcMine = dv.RenderOpen()) 
      { 
       drawImagesOnDrawingContext(dcMine); 
       dcMine.Close(); 
      } 
      RenderTargetBitmap rtb = new RenderTargetBitmap(200, 200, 96, 96, PixelFormats.Pbgra32); 
      rtb.Render(dv); 
      return rtb; 
     } 

     private void drawImagesOnDrawingContext(System.Windows.Media.DrawingContext dc) 
     { 
      //how to draw shadow on bi? 
      BitmapImage bi = new BitmapImage(new Uri(@"D:\mytemp\img1.jpg")); 
      dc.DrawImage(bi, new Rect(50, 50, 100, 100)); 

      //how to draw shadow on bi1 
      BitmapImage bi1 = new BitmapImage(new Uri(@"D:\mytemp\img2.jpg")); 
      dc.DrawImage(bi1, new Rect(30, 30, 100, 100)); 
     } 

    } 

注意由下SvenG建議,要添加效果的基本元素的溶液,不適合我,因爲它給出了一個陰影,整個元素,而不是單獨的圖像我畫工作。例如,如果我有兩個重疊的DrawImage,則建議的解決方案會考慮整體情況來繪製陰影。上方圖像的陰影將不會繪製在下方圖像上。

此外,我想創建一個使用getBitmap功能如上圖所示的繪製的圖像與陰影導出位圖。

+0

是位圖透明?即,是否要爲位圖的單個像素或每個位圖的矩形陰影? – GazTheDestroyer 2012-03-26 07:32:26

+0

@GazTheDestroyer位圖可以是透明的,因此每個位圖的矩形陰影將不起作用。但是,現在我無法弄清楚如何繪製矩形陰影! – AmaltasCoder 2012-03-26 07:40:52

回答

4

有一個老PushEffect()通話DrawingContext是會做你需要什麼,但像這樣BitmapEffect是過時的。

BitmapEffect的更換是Effect類。有一個名爲DropShadowEffect的子類,它正是你所追求的,但不幸的是,正如SvenG所說,這不能直接應用於位圖。

支持應用效果

最低級別元素是DrawingVisual類。這不是太糟糕,因爲DrawingVisual是一個非常輕量級的課程。沒有佈局開銷。您最好的選擇是創建自己的位圖DrawingVisual,並將該視覺的Effect屬性設置爲DropShadowEffect。顯然,如果你有成千上萬的位圖,它可能不是一個可行的解決方案。

所有這一切都可以在代碼完成,雖然沒有OnRender()因爲每個視覺都有自己的呈現上下文。但是,爲了使DrawingVisuals正確渲染,您需要告訴框架。

您需要重寫您的自定義元素中的兩個方法才能看到這些圖像:VisualChildrenCount表示您有多少個孩子,以及GetVisualChild()將它們返回給系統。因此,您需要保留一組可用的視覺效果。如果你想對他們進行測試,你也可以撥打AddVisualChild()AddLogicalChild()

public class MyDrawingView : FrameworkElement 
{ 
    List<DrawingVisual> _visuals = new List<DrawingVisual>(); 

    public MyDrawingView() 
    { 
     CreateVisuals(); 
    } 

    //Gets a bitmap rendering of the visual and its children for saving as image file 
    public RenderTargetBitmap GetBitmap() 
    { 
     var rtb = new RenderTargetBitmap(200, 200, 96, 96, PixelFormats.Pbgra32); 
     rtb.Render(this); 
     return rtb; 
    } 

    protected override int VisualChildrenCount 
    { 
     get 
     { 
      return _visuals.Count; 
     } 
    } 

    protected override Visual GetVisualChild(int index) 
    { 
     return _visuals[index]; 
    } 

    private void CreateVisuals() 
    { 
     CreateVisualForBitmap(@"D:\mytemp\img1.jpg", new Rect(50, 50, 100, 100)); 
     CreateVisualForBitmap(@"D:\mytemp\img2.jpg", new Rect(30, 30, 100, 100)); 
    } 

    private void CreateVisualForBitmap(string bitmapPath, Rect bounds) 
    { 
     var bitmap = new BitmapImage(new Uri(bitmapPath)); 
     var visual = new DrawingVisual(); 
     visual.Effect = new DropShadowEffect(); 

     using (DrawingContext dc = visual.RenderOpen()) 
     { 
      dc.DrawImage(bitmap, bounds); 
     } 

     _visuals.Add(visual); 
     AddVisualChild(visual); 
     AddLogicalChild(visual); 
    } 
} 
+0

你如何建議我從這張圖中創建一個可以保存爲圖像文件的位圖?我使用我原來的代碼中顯示的getBitmap函數來做到這一點。 – AmaltasCoder 2012-03-26 09:10:16

+0

已經在上面添加了GetBitmap()函數。 – GazTheDestroyer 2012-03-26 09:20:21

+0

這確實有用!我遇到的一個問題是,儘管我的應用程序不會有成千上萬的位圖,但它可以在用戶照片中創建數百個位圖。我可以在用戶在屏幕上繪製時使用重新調整大小的位圖來節省內存,但在導出最終圖像時,我想使用完整的位圖;所以內存可能是一個問題,因爲它似乎所有的位圖將被加載在一起。有沒有一種方法可以順序加載位圖? – AmaltasCoder 2012-03-26 11:22:18

1

下面的代碼添加到您的OnRenderMethod:

.... 

    dc.DrawImage(bi, new Rect(50, 50, 100, 100)); 

    // Create DropShadow 
    DropShadowEffect effect = new DropShadowEffect(); 
    effect = new DropShadowEffect(); 
    effect.Color = Colors.Gray; 
    effect.Direction = 45; 
    this.Effect = effect; 
+0

該解決方案部分解決了我的問題。我遇到的問題是,如果我有兩個重疊的DrawImage,這個解決方案會考慮到整體。上方圖像的陰影將不會繪製在下方圖像上。 – AmaltasCoder 2012-01-20 06:35:51

+0

嗨SvenG,你還可以建議我如何解決上面評論中描述的問題。 – AmaltasCoder 2012-01-23 06:48:38

+1

Amaltas,問題是效果只能應用於UIElements,這就是我在這裏所做的:無論使用drawingContext繪製多少張圖像,您的DrawingView都有一個Effect。 從我的角度來看,有一個FrameworkElement並在其上繪製多個BitmapImages感覺不知何故。 爲什麼不創建一個UserControl或一個包含您的DrawingView元素和另外的圖像控件與你想要顯示的圖像的風格? – SvenG 2012-01-23 11:00:44