Tải bản đầy đủ (.pdf) (8 trang)

Tài liệu Đồ hoạ, đa phương tiện ( Mutilmedia) và In ấn Đồ họa phần 3 pdf

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (159.86 KB, 8 trang )

using System;
using System.Windows.Forms;
using System.Drawing;

public class PictureScroll : System.Windows.Forms.Form {

private System.Windows.Forms.PictureBox pictureBox1;
private System.Windows.Forms.Panel panel1;

// (Bỏ qua phần mã designer.)

private void PictureScroll_Load(object sender, System.EventArgs e) {

string text = "The quick brown fox jumps over the lazy dog.";
Font font = new Font("Tahoma", 20);

// Tạo một hình bitmap trong-bộ-nhớ.
Bitmap b = new Bitmap(600, 600);
Graphics g = Graphics.FromImage(b);
g.FillRectangle(Brushes.White, new Rectangle(0, 0, b.Width,
b.Height));

// Vẽ nhiều dòng text lên hình bitmap.
for (int i=0; i < 10; i++) {
g.DrawString(text, font, Brushes.Black, 50, 50 + i*60);
}

// Hiển thị hình bitmap trong PictureBox.
pictureBox1.BackgroundImage = b;
pictureBox1.Size = b.Size;
}


}
1.1
Thực hiện chụp màn hình Desktop
V
V


Bạn cần lấy ảnh chụp của màn hình Desktop hiện thời.
#
#


Sử dụng các lời gọi Win32 API GetDesktopWindow, GetDC, và ReleaseDC
trong thư viện user32.dll. Ngoài ra, sử dụng GetCurrentObject trong thư viện
gdi32.dll.
.NET Framework không cung cấp lớp nào thực hiện việc chụp toàn bộ màn hình (thường
được đề cập là cửa sổ Desktop). Tuy nhiên, bạn có thể truy xuất các đặc tính này bằng
cách sử dụng P/Invoke với Win32 API.
Bước đầu tiên là tạo một lớp đóng gói các hàm Win32 API bạn cần sử dụng. Lớp dưới
đây sẽ khai báo các hàm này và sử dụng chúng trong phương thức công khai Capture để
trả về một đối t
ượng .NET Image chứa cửa sổ Desktop:
using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;

public class DesktopCapture {

[DllImport("user32.dll")]

private extern static IntPtr GetDesktopWindow();

[DllImport("user32.dll")]
private extern static IntPtr GetDC(IntPtr windowHandle);

[DllImport("gdi32.dll")]
private extern static IntPtr GetCurrentObject(IntPtr hdc,
ushort objectType);

[DllImport("user32.dll")]
private extern static void ReleaseDC( IntPtr hdc );

const int OBJ_BITMAP = 7;

public static Bitmap Capture() {

// Lấy Device Context của cửa sổ Desktop.
IntPtr desktopWindow = GetDesktopWindow();
IntPtr desktopDC = GetDC( desktopWindow );
// Lấy GDI handle của bức hình.
IntPtr desktopBitmap = GetCurrentObject(desktopDC, OBJ_BITMAP);

// Sử dụng handle để tạo đối tượng .NET Image.
Bitmap desktopImage = Image.FromHbitmap( desktopBitmap );

// Giải phóng Device Context và trả về bức hình.
ReleaseDC(desktopDC);
return desktopImage;
}
}


Hình 8.6 Chụp màn hình Desktop

Bước kế tiếp là tạo một client có thể sử dụng chức năng này. Form dưới đây (xem hình
8.6) sẽ hiển thị bức hình chụp được trong một PictureBox (nằm trong một Panel cuộn
được, như đã được mô tả trong mục 8.5).
public class ScreenCapture : System.Windows.Forms.Form {

private System.Windows.Forms.PictureBox pictureBox1;
private System.Windows.Forms.Panel panel1;

// (Bỏ qua phần mã designer.)

private void cmdCapture_Click(object sender, System.EventArgs e) {

pictureBox1.Image = DesktopCapture.Capture();
pictureBox1.Size = pictureBox1.Image.Size;
}
}
1.2
Sử dụng “double buffering” để tăng tốc độ vẽ lại
The image part with relationship ID rId5 was not fo und in the file.
V
V


Bạn cần tối ưu thao tác vẽ đối với một form thường xuyên được làm tươi, và
bạn muốn giảm hiện tượng rung hình (flicker).
#
#



Biểu diễn hình ảnh ở dạng hình bitmap trong-bộ-nhớ, rồi chép hình bitmap đã
hoàn chỉnh vào form.
Trong một vài ứng dụng, bạn thường xuyên phải vẽ lại form hoặc điều kiểm. Điều này
thường gặp khi thể hiện animation (hình động). Ví dụ, bạn có thể sử dụng Timer để làm
mất hiệu lực form mỗi giây. Khi đó, đoạn mã thực hiện thao tác vẽ có thể vẽ l
ại một bức
hình tại một vị trí mới, tạo cảm giác động. Cách tiếp cận này có một vấn đề: mỗi lần bạn
làm mất hiệu lực form, Windows sẽ vẽ lại nền cửa sổ (xóa form), và rồi chạy đoạn mã
thực hiện thao tác vẽ. Điều này có thể gây ra rung hình đáng kể.
“Double buffering” là một kỹ thuật bạn có thể hiện thực để giả
m hiện tượng rung hình.
Với “double buffering”, logic vẽ sẽ ghi một hình bitmap trong-bộ-nhớ, và hình này được
chép lên form vào cuối quá trình vẽ bằng một thao tác vẽ lại đơn lẻ trong suốt, nhờ đó mà
hiện tượng rung hình giảm một cách đáng kể.
Bước đầu tiên khi hiện thực “double buffering” là phải bảo đảm nền của form không tự
động được vẽ lại khi form bị mất hiệu lực. Đây là nguyên nhân lớn nhất gây ra rung hình
vì nó thay thế
bức hình của bạn bằng một frame trống (giả dụ chỉ là một phần nhỏ của
một giây). Để ngăn việc vẽ nền, bạn cần chép đè phương thức OnPaintBackground của
form để nó không nhận hành động nào. Bước thứ hai là sửa đổi đoạn mã thực hiện thao
tác vẽ để nó vẽ bức hình thành một hình bitmap trong-bộ-nhớ. Khi hoàn tất, hình bitmap
được chép vào form. Cách tiếp cận này bảo đả
m làm tươi là một thao tác vẽ lại đơn lẻ, và
drawing logic tốn nhiều thời gian đó sẽ không gây ra hiện tượng rung hình.
Ví dụ sau đây trình bày một bức hình (ở đây là logo của Windows XP) luân phiên lớn lên
và nhỏ lại trên form. Drawing logic được thực hiện trong phương thức thụ lý sự kiện
Form.Paint, và một Timer được sử dụng để làm mất hiệu lực form mỗi 10 mili-giây để
bức hình có thể được vẽ lại. Ngườ

i dùng có thể kích hoạt “double buffering” thông qua
một CheckBox trên form. Nếu không có “double buffering”, form bị rung đáng kể. Tuy
nhiên, khi “double buffering” được kích hoạt, bức hình lớn lên và nhỏ lại một cách mượt
mà, không còn độ rung nữa.
using System;
using System.Drawing;
using System.Drawing2D;
using System.Windows.Forms;

public class DoubleBuffering : System.Windows.Forms.Form {

private System.Windows.Forms.CheckBox chkUseDoubleBuffering;
private System.Windows.Forms.Timer tmrRefresh;

// (Bỏ qua phần mã designer.)

// Theo dõi kích thước bức hình,
// và kiểu animation (lớn lên hoặc nhỏ lại).
private bool isShrinking = false;
private int imageSize = 0;

// Lưu trữ logo sẽ được vẽ lên form.
private Image image;

private void DoubleBuffering_Load(object sender,
System.EventArgs e) {

// Nạp bức hình logo từ file.
image = Image.FromFile("image.bmp");


// Khởi động Timer để làm mất hiệu lực form.
tmrRefresh.Start();
}

private void tmrRefresh_Tick(object sender, System.EventArgs e) {

// Thay đổi kích thước bức hình dựa vào kiểu animation.
if (isShrinking) {
imageSize--;

}else {
imageSize++;
}

// Đổi hướng thay đổi kích thước nếu đến gần biên của form.
if (imageSize > (this.Width - 150)) {
isShrinking = true;

}else if (imageSize < 1) {
isShrinking = false;
}

×