1. Trang chủ
  2. » Công Nghệ Thông Tin

Các giải pháp lập trình CSharp- P42 doc

10 280 1

Đang tải... (xem toàn văn)

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 10
Dung lượng 2,62 MB

Nội dung

301 Chương 8: Đồ họa, đa phương tiện, và in ấn } private void Ellipse_MouseMove(object sender, MouseEventArgs e) { // Thu lấy ellipse gây ra sự kiện này. Control control = (Control)sender; if ((isDraggingA && control == ellipseA) || (isDraggingB && control == ellipseB)) { // Lấy offset. Point point = (Point)control.Tag; // Di chuyển điều kiểm. control.Left = e.X + control.Left - point.X; control.Top = e.Y + control.Top - point.Y; } } } 5. 5. Thêm tính năng cu n cho m t b c hìnhộ ộ ứ Thêm tính năng cu n cho m t b c hìnhộ ộ ứ   Bạn cần tạo một bức hình có thể cuộn được (bức hình có nội dung động).   Tạo khả năng cuộn tự động cho System.Windows.Forms.Panel bằng cách thiết lập Panel.AutoScroll là true và đặt một System.Windows.Forms.PictureBox chứa nội dung bức hình vào trong Panel . Khi bạn thiết lập Panel.AutoScroll là true , nếu điều kiểm nào đó trong Panel vượt quá đường biên của nó, Panel sẽ hiển thị thanh cuộn cho phép người dùng chuyển tiếp nội dung. Cách này đặc biệt tốt đối với các bức hình lớn. Bạn có thể nạp hoặc tạo bức hình trong bộ nhớ, gán nó vào một PictureBox (không có sự hỗ trợ nội tại nào cho việc cuộn PictureBox ), và rồi hiển thị PictureBox bên trong Panel . Chỉ có một vấn đề mà bạn cần nhớ là phải thiết lập kích thước của PictureBox bằng với kích thước thật của bức hình bạn muốn hiển thị. Ví dụ sau đây tạo một bức hình mô tả một văn bản. Bức hình được tạo từ một hình bitmap trong-bộ-nhớ, và nhiều dòng text được thêm vào bằng phương thức Graphics.DrawString . Kế đó, bức hình được kết với PictureBox ( PictureBox này được hiển thị trong một Panel cuộn được—xem hình 8.5). 302 Chương 8: Đồ họa, đa phương tiện, và in ấn Hình 8.5 Thêm tính năng cuộn cho bức hình với nội dung tùy biến 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++) { 303 Chương 8: Đồ họa, đa phương tiện, và in ấn 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; } } 6. 6. Th c hi n ch p màn hình Desktopự ệ ụ Th c hi n ch p màn hình Desktopự ệ ụ   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 ); 304 Chương 8: Đồ họa, đa phương tiện, và in ấn 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 305 Chương 8: Đồ họa, đa phương tiện, và in ấn 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; } } 7. 7. S d ng “double buffering” đ tăng t c đ v l iử ụ ể ố ộ ẽ ạ S d ng “double buffering” đ tăng t c đ v l iử ụ ể ố ộ ẽ ạ   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. 306 Chương 8: Đồ họa, đa phương tiện, và in ấn 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) { 307 Chương 8: Đồ họa, đa phương tiện, và in ấn // 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; } // Vẽ lại form. this.Invalidate(); } private void DoubleBuffering_Paint(object sender, System.Windows.Forms.PaintEventArgs e) { Graphics g; Bitmap drawing = null; if (chkUseDoubleBuffering.Checked) { // "Double buffering" đang được sử dụng. // Tạo một bitmap trong-bộ-nhớ mô tả bề mặt của form. drawing = new Bitmap(this.Width, this.Height, e.Graphics); g = Graphics.FromImage(drawing); }else { // "Double buffering" không được sử dụng. 308 Chương 8: Đồ họa, đa phương tiện, và in ấn // Vẽ trực tiếp lên form. g = e.Graphics; } g.SmoothingMode = SmoothingMode.HighQuality; // Vẽ nền. g.FillRectangle(Brushes.Yellow, new Rectangle(new Point(0, 0), this.ClientSize)); // Vẽ bức hình logo. g.DrawImage(image, 50, 50, 50 + imageSize, 50 + imageSize); // Nếu sử dụng "double buffering", chép hình bitmap // đã hoàn tất trong bộ nhớ vào form. if (chkUseDoubleBuffering.Checked) { e.Graphics.DrawImageUnscaled(drawing, 0, 0); g.Dispose(); } } protected override void OnPaintBackground( System.Windows.Forms.PaintEventArgs pevent) { // Không làm gì cả. } } 8. 8. Hi n th hình d ng thumbnailể ị ở ạ Hi n th hình d ng thumbnailể ị ở ạ   Bạn cần hiển thị các bức hình trong một thư mục ở dạng thumbnail.   Đọc bức hình từ file bằng phương thức tĩnh FromFile của lớp System.Drawing.Image . Kế đó, bạn có thể thu lấy hình thumbnail bằng phương thức Image.GetThumbnailImage . 309 Chương 8: Đồ họa, đa phương tiện, và in ấn Lớp Image cung cấp chức năng tạo thumbnail thông qua phương thức GetThumbnailImage . Bạn chỉ cần truyền chiều rộng và chiều cao của hình thumbnail bạn muốn (tính bằng pixel), và lớp Image sẽ tạo một đối tượng Image mới phù hợp với tiêu chuẩn này. Việc khử méo dạng răng cưa (antialiasing) được sử dụng khi thu nhỏ bức hình để bảo đảm chất lượng bức hình tốt nhất có thể được, mặc dù một số vết mờ và thiếu hụt một vài tiểu tiết là không thể tránh khỏi (khử méo dạng răng cưa là quá trình loại bỏ các rìa lởm chởm, thường có trong các bức hình đã được thay đổi kích thước, bằng cách tô bóng với một màu trung gian). Ngoài ra, bạn có thể cung cấp một callback để tạo thumbnail một cách bất đồng bộ. Khi tạo một thumbnail, việc quan trọng là phải bảo đảm tỉ số giữa hai chiều vẫn như cũ (hằng số). Ví dụ, nếu bạn thu nhỏ một bức hình kích thước 200x100 thành một thumbnail kích thước 50x50, chiều rộng sẽ bị nén còn một phần tư và chiều cao bị nén còn một nửa, điều này làm méo bức hình. Để bảo đảm tỉ lệ này vẫn như cũ, bạn có thể thay đổi chiều rộng hoặc chiều cao thành một kích thước cố định rồi điều chỉnh chiều còn lại cho cân xứng. Ví dụ dưới đây đọc một file bitmap và tạo một thumbnail kích thước không lớn hơn 50x50 (vẫn bảo toàn tỉ lệ gốc): using System; using System.Drawing; using System.Windows.Forms; public class Thumbnails : System.Windows.Forms.Form { // (Bỏ qua phần mã designer.) Image thumbnail; private void Thumbnails_Load(object sender, System.EventArgs e) { Image img = Image.FromFile("test.jpg"); int thumbnailWidth = 0, thumbnailHeight = 0; // Điều chỉnh chiều lớn hơn là 50 pixel. // Việc này bảo đảm thumbnail sẽ không lớn hơn 50x50 pixel. // Nếu muốn hiển thị nhiều thumbnail, bạn sẽ phải dùng // một hình vuông 50x50 pixel cho mỗi thumbnail. if (img.Width > img.Height) { thumbnailWidth = 50; thumbnailHeight = Convert.ToInt32(((50F / img.Width) * img.Height)); 310 Chương 8: Đồ họa, đa phương tiện, và in ấn }else { thumbnailHeight = 50; thumbnailWidth = Convert.ToInt32(((50F / img.Height) * img.Width)); } thumbnail = img.GetThumbnailImage(thumbnailWidth, thumbnailHeight, null, IntPtr.Zero); } private void Thumbnails_Paint(object sender, System.Windows.Forms.PaintEventArgs e) { e.Graphics.DrawImage(thumbnail, 10, 10); } } 9. 9. Phát ti ng “beep” c a h th ngế ủ ệ ố Phát ti ng “beep” c a h th ngế ủ ệ ố   Bạn cần phát một âm thanh đơn giản, chẳng hạn tiếng “beep” của hệ thống.   Sử dụng một hàm không-được-quản-lý Win32 API như Beep hay sndPlaySound , hoặc gọi hàm Beep của Microsoft Visual Basic .NET . .NET Framework không chứa bất kỳ lớp được-quản-lý nào thực hiện việc chơi các file âm thanh, ngay cả tiếng “beep” của hệ thống cũng không. Tuy nhiên, bạn có thể dễ dàng vượt qua trở ngại này bằng Win32 API hoặc Visual Basic .NET (cấp hàm Beep thông qua lớp Microsoft.VisualBasic.Interaction ). Trong trường hợp thứ hai, bạn phải thêm một tham chiếu đến Microsoft.VisualBasic.dll (có trong tất cả các phiên bản của .NET Framework). Ví dụ sau đây sử dụng cả hàm API Beep và hàm Visual Basic Beep . Chú ý là hàm API sử dụng loa gắn trong của máy tính và phát âm thanh với tần số (tính bằng Hertz, nằm trong khoảng từ 37 đến 32,767) và thời gian (tính bằng mili-giây) cho trước. Cách này sẽ không phát bất kỳ âm thanh nào nếu máy tính không có loa gắn trong. Mặt khác, hàm Visual Basic Beep phát tiếng “beep” chuẩn của hệ thống (là một file WAV). Cách này sẽ không phát bất kỳ âm thanh nào nếu máy tính không có card âm thanh, nếu card âm thanh không được kết nối với loa gắn ngoài, hoặc nếu Windows được cấu hình là không phát âm thanh (thông qua phần Sounds and Audio Devices trong Control Panel). . 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ử. không thể tránh khỏi (khử méo dạng răng cưa là quá trình loại bỏ các rìa lởm chởm, thường có trong các bức hình đã được thay đổi kích thước, bằng cách tô bóng với một màu trung gian). Ngoài ra,. System.Windows.Forms.Panel bằng cách thiết lập Panel.AutoScroll là true và đặt một System.Windows.Forms.PictureBox chứa nội dung bức hình vào trong Panel . Khi bạn thiết lập Panel.AutoScroll

Ngày đăng: 08/07/2014, 17:20

TỪ KHÓA LIÊN QUAN