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 metode BeginContainer dari objek Graphics. 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 objek Graphics dan wadah di dalam objek tersebut Graphics. Transformasi objek Graphics di dunia adalah translasi sebanyak 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 di dalam kontainer diubah terlebih dahulu oleh transformasi dunia dari kontainer (rotasi) dan kemudian oleh transformasi dunia dari objek Graphics (translasi). Persegi panjang yang digambar dari luar kontainer hanya diubah oleh transformasi Graphics dunia objek (terjemahan). Ilustrasi berikut menunjukkan dua persegi panjang:

Ilustrasi yang memperlihatkan kontainer berlapis.

Kliping dalam Kontainer Berlapis

Contoh berikut menunjukkan bagaimana kontainer terduplikasi menangani area pemangkasan. 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 dipotong oleh area pemotongan persegi panjang dari objek Graphics.

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 garis yang terpotong.

Ilustrasi yang memperlihatkan kontainer berlapis dengan garis terklip.

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 area kliping dari kontainer dan objek Graphics, item yang digambar dari dalam kontainer akan terpotong oleh perpotongan dua area kliping tersebut.

Pengaturan Kualitas 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 sebuah objek Graphics 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 mengambil tiga string: satu dari kontainer dalam, satu dari kontainer luar, dan satu dari objek Graphics itu 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 wadah bagian dalam dan dari objek Graphics dihaluskan dengan anti-aliasing. String yang digambar dari kontainer luar tidak dihaluskan dengan antialias karena TextRenderingHint properti diatur ke SingleBitPerPixel.

Ilustrasi yang memperlihatkan string yang ditarik dari kontainer bertumpuk.

Lihat juga