Bagikan melalui


Menggunakan Kontainer Grafis Berlapis

GDI+ menyediakan kontainer yang dapat Anda gunakan untuk mengganti sementara atau menambah bagian status dalam Graphics objek. Anda membuat kontainer dengan memanggil BeginContainer metode Graphics objek. Anda dapat memanggil BeginContainer berulang kali untuk membentuk kontainer berlapis. Setiap panggilan ke BeginContainer harus dipasangkan dengan panggilan ke EndContainer.

Transformasi dalam Kontainer Berlapis

Contoh berikut membuat Graphics objek dan kontainer dalam objek tersebut Graphics . Transformasi Graphics dunia objek adalah terjemahan 100 unit ke arah x dan 80 unit ke arah y. Transformasi dunia kontainer adalah rotasi 30 derajat. Kode melakukan panggilan DrawRectangle(pen, -60, -30, 120, 60) dua kali. Panggilan pertama ke DrawRectangle berada di dalam kontainer; yaitu, panggilan berada di antara panggilan ke BeginContainer dan EndContainer. Panggilan kedua ke DrawRectangle adalah setelah panggilan ke EndContainer.

Graphics graphics = e.Graphics;
Pen pen = new Pen(Color.Red);
GraphicsContainer graphicsContainer;
graphics.FillRectangle(Brushes.Black, 100, 80, 3, 3);

graphics.TranslateTransform(100, 80);

graphicsContainer = graphics.BeginContainer();
graphics.RotateTransform(30);
graphics.DrawRectangle(pen, -60, -30, 120, 60);
graphics.EndContainer(graphicsContainer);

graphics.DrawRectangle(pen, -60, -30, 120, 60);
Dim graphics As Graphics = e.Graphics
Dim pen As New Pen(Color.Red)
Dim graphicsContainer As GraphicsContainer
graphics.FillRectangle(Brushes.Black, 100, 80, 3, 3)

graphics.TranslateTransform(100, 80)

graphicsContainer = graphics.BeginContainer()
graphics.RotateTransform(30)
graphics.DrawRectangle(pen, -60, -30, 120, 60)
graphics.EndContainer(graphicsContainer)

graphics.DrawRectangle(pen, -60, -30, 120, 60)

Dalam kode sebelumnya, persegi panjang yang digambar dari dalam kontainer diubah terlebih dahulu oleh transformasi dunia kontainer (rotasi) dan kemudian oleh transformasi Graphics dunia objek (terjemahan). Persegi panjang yang digambar dari luar kontainer hanya diubah oleh transformasi Graphics dunia objek (terjemahan). Ilustrasi berikut menunjukkan dua persegi panjang:

Illustration that shows nested containers.

Kliping dalam Kontainer Berlapis

Contoh berikut menunjukkan bagaimana kontainer berlapis menangani wilayah kliping. Kode membuat Graphics objek dan kontainer dalam objek tersebut Graphics . Wilayah kliping Graphics objek adalah persegi panjang, dan wilayah kliping kontainer adalah elips. Kode melakukan dua panggilan ke DrawLine metode . Panggilan pertama ke DrawLine berada di dalam kontainer, dan panggilan kedua ke DrawLine berada di luar kontainer (setelah panggilan ke EndContainer). Baris pertama diklip oleh persimpangan dua wilayah kliping. Baris kedua hanya diklip oleh wilayah Graphics kliping persegi panjang objek.

Graphics graphics = e.Graphics;
GraphicsContainer graphicsContainer;
Pen redPen = new Pen(Color.Red, 2);
Pen bluePen = new Pen(Color.Blue, 2);
SolidBrush aquaBrush = new SolidBrush(Color.FromArgb(255, 180, 255, 255));
SolidBrush greenBrush = new SolidBrush(Color.FromArgb(255, 150, 250, 130));

graphics.SetClip(new Rectangle(50, 65, 150, 120));
graphics.FillRectangle(aquaBrush, 50, 65, 150, 120);

graphicsContainer = graphics.BeginContainer();
// Create a path that consists of a single ellipse.
GraphicsPath path = new GraphicsPath();
path.AddEllipse(75, 50, 100, 150);

// Construct a region based on the path.
Region region = new Region(path);
graphics.FillRegion(greenBrush, region);

graphics.SetClip(region, CombineMode.Replace);
graphics.DrawLine(redPen, 50, 0, 350, 300);
graphics.EndContainer(graphicsContainer);

graphics.DrawLine(bluePen, 70, 0, 370, 300);
Dim graphics As Graphics = e.Graphics
Dim graphicsContainer As GraphicsContainer
Dim redPen As New Pen(Color.Red, 2)
Dim bluePen As New Pen(Color.Blue, 2)
Dim aquaBrush As New SolidBrush(Color.FromArgb(255, 180, 255, 255))
Dim greenBrush As New SolidBrush(Color.FromArgb(255, 150, 250, 130))

graphics.SetClip(New Rectangle(50, 65, 150, 120))
graphics.FillRectangle(aquaBrush, 50, 65, 150, 120)

graphicsContainer = graphics.BeginContainer()
' Create a path that consists of a single ellipse.
Dim path As New GraphicsPath()
path.AddEllipse(75, 50, 100, 150)

' Construct a region based on the path.
Dim [region] As New [Region](path)
graphics.FillRegion(greenBrush, [region])

graphics.SetClip([region], CombineMode.Replace)
graphics.DrawLine(redPen, 50, 0, 350, 300)
graphics.EndContainer(graphicsContainer)

graphics.DrawLine(bluePen, 70, 0, 370, 300)

Ilustrasi berikut menunjukkan dua baris yang diklip:

Illustration that shows a nested container with clipped lines.

Seperti yang ditunjukkan oleh dua contoh sebelumnya, transformasi dan wilayah kliping bersifat kumulatif dalam kontainer berlapis. Jika Anda mengatur transformasi dunia kontainer dan Graphics objek, kedua transformasi akan berlaku untuk item yang diambil dari dalam kontainer. Transformasi kontainer akan diterapkan terlebih dahulu, dan transformasi Graphics objek akan diterapkan kedua. Jika Anda mengatur wilayah kliping kontainer dan Graphics objek, item yang digambar dari dalam kontainer akan dipotong oleh persimpangan dua wilayah kliping.

Kualitas Pengaturan dalam Kontainer Berlapis

Pengaturan kualitas (SmoothingMode, TextRenderingHint, dan sejenisnya) dalam kontainer berlapis tidak kumulatif; melainkan, pengaturan kualitas kontainer untuk sementara menggantikan pengaturan Graphics kualitas objek. Saat Anda membuat kontainer baru, pengaturan kualitas untuk kontainer tersebut diatur ke nilai default. Misalnya, Anda memiliki Graphics objek dengan mode penghalusan AntiAlias. Saat Anda membuat kontainer, mode penghalusan di dalam kontainer adalah mode penghalusan default. Anda bebas mengatur mode smoothing kontainer, dan item apa pun yang diambil dari dalam kontainer akan digambar sesuai dengan mode yang Anda tetapkan. Item yang digambar setelah panggilan ke EndContainer akan digambar sesuai dengan mode smoothing (AntiAlias) yang ada sebelum panggilan ke BeginContainer.

Beberapa Lapisan Kontainer Berlapis

Anda tidak terbatas pada satu kontainer dalam objek Graphics . Anda dapat membuat urutan kontainer, masing-masing bersarang di sebelumnya, dan Anda dapat menentukan transformasi dunia, wilayah kliping, dan pengaturan kualitas masing-masing kontainer berlapis tersebut. Jika Anda memanggil metode menggambar dari dalam kontainer terdalam, transformasi akan diterapkan secara berurutan, dimulai dengan kontainer terdalam dan diakhiri dengan kontainer terluar. Item yang digambar dari dalam kontainer terdalam akan dipotong oleh persimpangan semua wilayah kliping.

Contoh berikut membuat Graphics objek dan mengatur petunjuk penyajian teksnya ke AntiAlias. Kode membuat dua kontainer, satu berlapis di dalam yang lain. Petunjuk penyajian teks dari kontainer luar diatur ke SingleBitPerPixel, dan petunjuk penyajian teks dari kontainer dalam diatur ke AntiAlias. Kode menggambar tiga string: satu dari kontainer dalam, satu dari kontainer luar, dan satu dari objek itu Graphics sendiri.

Graphics graphics = e.Graphics;
GraphicsContainer innerContainer;
GraphicsContainer outerContainer;
SolidBrush brush = new SolidBrush(Color.Blue);
FontFamily fontFamily = new FontFamily("Times New Roman");
Font font = new Font(fontFamily, 36, FontStyle.Regular, GraphicsUnit.Pixel);

graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;

outerContainer = graphics.BeginContainer();

graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SingleBitPerPixel;

innerContainer = graphics.BeginContainer();
graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
graphics.DrawString(
   "Inner Container",
   font,
   brush,
   new PointF(20, 10));
graphics.EndContainer(innerContainer);

graphics.DrawString(
   "Outer Container",
   font,
   brush,
   new PointF(20, 50));

graphics.EndContainer(outerContainer);

graphics.DrawString(
   "Graphics Object",
   font,
   brush,
   new PointF(20, 90));
Dim graphics As Graphics = e.Graphics
Dim innerContainer As GraphicsContainer
Dim outerContainer As GraphicsContainer
Dim brush As New SolidBrush(Color.Blue)
Dim fontFamily As New FontFamily("Times New Roman")
Dim font As New Font( _
   fontFamily, _
   36, _
   FontStyle.Regular, _
   GraphicsUnit.Pixel)

graphics.TextRenderingHint = _
System.Drawing.Text.TextRenderingHint.AntiAlias

outerContainer = graphics.BeginContainer()

graphics.TextRenderingHint = _
    System.Drawing.Text.TextRenderingHint.SingleBitPerPixel

innerContainer = graphics.BeginContainer()
graphics.TextRenderingHint = _
    System.Drawing.Text.TextRenderingHint.AntiAlias
graphics.DrawString( _
   "Inner Container", _
   font, _
   brush, _
   New PointF(20, 10))
graphics.EndContainer(innerContainer)

graphics.DrawString("Outer Container", font, brush, New PointF(20, 50))

graphics.EndContainer(outerContainer)

graphics.DrawString("Graphics Object", font, brush, New PointF(20, 90))

Ilustrasi berikut menunjukkan tiga string. String yang diambil dari kontainer dalam dan dari Graphics objek dihaluskan dengan antialias. String yang digambar dari kontainer luar tidak dihaluskan dengan antialias karena TextRenderingHint properti diatur ke SingleBitPerPixel.

Illustration that shows the strings drawn from nested containers.

Baca juga