www.rolandk.de
- Aktuelle Themen zu .Net -
Achtung: Hier handelt es sich um meine alte Seite.
Die aktuelle ist unter folgendem Link erreichbar: www.rolandk.de/wp/
Home Tutorials Direct2D und DirectWrite Chapter 4 - Bilder laden und zeichnen




















































Chapter 4 - Bilder laden und zeichnen
Donnerstag, den 29. Juli 2010 um 17:54 Uhr

 

 

Bitmaps laden

In den letzten 3 Kapiteln wurden bereits die wichtigsten Themen behandelt, außer einer: Das zeichnen von Bitmaps. Wer das bis jetzt schon einmal probieren wollte, ist eventuell bereits auf ein Problem gestoßen: Es gibt keine Methode, mit der ein Bitmap aus einer Datei geladen werden kann. Zumindest in der SlimDX Version, die für dieses Tutorial verwendet wurde (Juni 2010) existiert eine solche Methode nicht. Grund dafür ist, dass das normalerweise über WIC (Windows Image Component) erfolgt, diese API aber nicht im Umfang von SlimDX enthalten ist. Allerdings hat man eine andere Möglichkeit: Man kann etwa ein System.Drawing.Bitmap erzeugen und dessen Inhalt dann in ein neues Direct2D Bitmap kopieren. Folgende Methoden erfüllen genau diesen Zweck:

  1. ///
  2. /// Loads a Direct2D bitmap from the given file.
  3. //
  4. public D2D.Bitmap LoadBitmap(string file)
  5. {
  6. D2D.Bitmap result = null;
  7.  
  8. //Create Gdi Bitmap
  9. Bitmap drawingBitmap = Bitmap.FromFile(file) as Bitmap;
  10.  
  11. //Load the Direct2D resource from the gdi resource
  12. result = LoadBitmap(drawingBitmap);
  13.  
  14. //Dispose the gdi bitmap after loading
  15. drawingBitmap.Dispose();
  16.  
  17. return result;
  18. }
  19.  
  20. ///
  21. /// Load a Direct2D bitmap from the given gdi resource.
  22. ///
  23. public D2D.Bitmap LoadBitmap(Bitmap drawingBitmap)
  24. {
  25. D2D.Bitmap result = null;
  26.  
  27. //Lock the gdi resource
  28. BitmapData drawingBitmapData = drawingBitmap.LockBits(
  29. new Rectangle(0, 0, drawingBitmap.Width, drawingBitmap.Height),
  30. ImageLockMode.ReadOnly, PixelFormat.Format32bppPArgb);
  31.  
  32. //Prepare loading the image from gdi resource
  33. DataStream dataStream = new DataStream(
  34. drawingBitmapData.Scan0,
  35. drawingBitmapData.Stride * drawingBitmapData.Height,
  36. true, false);
  37. D2D.BitmapProperties properties = new D2D.BitmapProperties();
  38. properties.PixelFormat = new D2D.PixelFormat(
  39. DXGI.Format.B8G8R8A8_UNorm,
  40. D2D.AlphaMode.Premultiplied);
  41.  
  42. //Load the image from the gdi resource
  43. result = new D2D.Bitmap(
  44. m_renderTarget,
  45. new Size(drawingBitmap.Width, drawingBitmap.Height),
  46. dataStream, drawingBitmapData.Stride,
  47. properties);
  48.  
  49. //Unlock the gdi resource
  50. drawingBitmap.UnlockBits(drawingBitmapData);
  51.  
  52. return result;
  53. }

Diese beiden Methoden geben dem Entwickler zwei Möglichkeiten: Die Erste lädt ein Bitmap direkt aus einer Datei und die Zweite kopiert den Inhalt eines vorhandenen System.Drawing.Bitmaps in ein neues Direct2D Bitmap. Dadurch reicht jetzt etwa folgender Code, um ein Direct2D Bitmap aus einer lokalen Ressource zu laden:

  1. //Load the bitmap
  2. m_puzzleBitmapGdi = Properties.Resources.Puzzle;
  3. m_puzzleBitmap = LoadBitmap(m_puzzleBitmapGdi);

 

Bitmaps zeichnen

Das Zeichnen eines Bitmaps ist gewohnt einfach. Im einfachsten Fall reicht sogar ein einziger Aufruf mit einem einzigen Parameter:

  1. m_renderTarget.DrawBitmap(m_puzzleBitmap);

Hiermit wird das Bitmap an die Position 0,0 gezeichnet - ganz ohne irgendwelche Größenänderungen oder Transparenz. Alternativ kann ein Rechteck mitgegeben werden, in das das Bitmap gezeichnet werden soll. Die Größe des Bitmaps wird dabei dynamisch an das Rechteck angepasst. Zusätzlich kann noch ein Transparenzfaktor mitgegeben werden. Folgendes Coding nutzt diese Möglichkeiten, um eine ähnliche Massenanzeige wie in Kapitel 2 zu zeichnen:

  1. m_renderTarget.Clear(new Color4(this.BackColor));
  2.  
  3. //Perform all Direct2D rendering here
  4. m_renderTarget.FillRectangle(
  5. m_backBrushEx,
  6. new Rectangle(new Point(), this.Size));
  7.  
  8. //Apply quality
  9. D2D.InterpolationMode interpolationMode = D2D.InterpolationMode.NearestNeighbor;
  10. if (m_chkHighQuality.Checked) { interpolationMode = D2D.InterpolationMode.Linear; }
  11.  
  12. //Draw all images
  13. int imageCount = 0;
  14. float transparency = m_chkTransparent.Checked ? 0.4f : 1f;
  15. int imageWidth = m_scrollRectangleSize.Value;
  16. int imageHeight = m_scrollRectangleSize.Value;
  17. for (int loopX = 0; loopX < this.Width / imageWidth + 1; loopX++)
  18. {
  19. for (int loopY = 0; loopY < this.Height / imageHeight + 1; loopY++)
  20. {
  21. //Draw the bitmap
  22. m_renderTarget.DrawBitmap(
  23. m_puzzleBitmap,
  24. new RectangleF(
  25. loopX * imageWidth, loopY * imageHeight,
  26. imageWidth, imageHeight),
  27. transparency,
  28. interpolationMode);
  29. imageCount++;
  30. }
  31. }

 

Weitere Themen

Dieses Tutorial hat gezeigt, dass Direct2D durchaus auch für .Net Entwickler interessant sein kann. Zwar wurde es hier immer nur innerhalb von Windows.Forms Anwendungen gezeigt, doch in WPF kann man Direct2D genauso einbetten. Natürlich bietet Direct2D noch eine große Palette weiterer Features. Die Artikel auf Msdn beschreiben die Möglichkeiten von Direct2D sehr gut und können für weitere Themen herangezogen werden. Zusätzlich bietet auch das zum jeweiligen Zeitpunkt aktuelle DirectX SDK eine umfangreiche Dokumentation zur API.

 

Quellen

  • DirectX SDK
    Die Beispiele und die Dokumentation im DirectX SDK sind zwar auf C++ ausgelegt, da sich SlimDX stark an der originalen API orientiert, ist das SDK aber dennoch sehr hilfreich.
  • Msdn
    Auf Msdn findet man eine sehr umfangreiche Hilfe zu Direct2D und DirectWrite.
  • SlimDX
    Hauptseite des SlimDX-Projekts.

 

Siehe auch...

 

Kommentar hinzufügen

Ihr Name:
Kommentar: