Tài liệu Đọc ảnh trong C# - Pdf 86

Admin
Ngày tham gia: Chủ nhật Tháng 11 25, 2007 2:23 pm
Bài viết: 338
Given: 5 thanks
Received: 191 thanks
Bài này nói qua một số điều cần biết để có thể đọc được file ảnh, chỉnh sửa trên từng pixel
của ảnh trong C#. Không làm 1 đề cụ thể nào, nhưng các bước tiến hành của các đề bài cụ
thể thì cũng na ná như vậy. Kèm theo 1 cái code ví dụ để mọi người ngâm cứu.
* Đọc ảnh trong C#:
Dùng 1 đối tượng của lớp Bitmap để tạo mới 1 ảnh( mới hoàn toàn hay đọc mới từ file).
VD:
Bitmap bm = new Bitmap("C:\Pictures\abc.jpg");
// lệnh trên khai báo 1 biến bm, là 1 ảnh lấy từ C:\Pictures\abc.jpg
* In ảnh lên form:
Đọc được vào biến rồi, giờ phải in ra để mọi người cùng thấy đúng không? Dùng phương
thức DrawImage để hiện ảnh lên
Ví dụ: Hiện ảnh lên form chính
Graphics gr = CreateGraphics();// Khởi tạo đồ hoạ trên form chính
gr.DrawImage(bm,0,0);
gr.Dispose()// Giải phóng biến graphics
Các tham số của DrawImage là:
bm: ảnh cần đưa ra màn hình
0,0 : toạ độ góc trên bên trái của ảnh
* Truy xuất và thay đổi từng pixel ảnh:
**Cấu trúc file ảnh:
Là 1 ma trận 2 chiều các pixel, ảnh thông thường là ảnh 24 bít, tức là mỗi pixel 24 bits= 3
bytes. Chúng ta tưởng tượng như sau: pixel đầu tiên của ảnh chiếm 3 byte đầu (0,1,2); pixel
thứ 2 chiếm 3 byte tiếp (3,4,5); cứ như thế...
Để biết ảnh bm có kích thước bao nhiêu, C# cung cấp 2 thuộc tính:
bm.Width: số pixel trên 1 hàng(độ rộng)
bm.Height: số hàng(độ cao)

PixelFormat.24bitrgp);
int stride = bmData.Stride;
int nOffset = stride - bm.Width*3;
//nOffset chính là cái rìa của bức ảnh, khi con trỏ xử lý đến pixel cuối cùng của hàng, thì
muốn xuống //hàng kế tiếp, ta phải bỏ qua cái rìa này bằng cách cộng thêm địa chỉ con trỏ
với nOffset
byte *p = (byte*)bmData.Scan0;
//p sẽ trỏ đến địa chỉ đẩu của ảnh
int x,y;
for(y = 0; y<bm.Height; y++)
{
for(x = 0; x<bm.Width; x++)
{
//Xử lý 3 byte của pixel
p[0] = 255;
p[1] = 255;
p[2] = 255;
//Chuyển con trỏ sang pixel kế tiếp
p += 3; // 2 pixel kế tiếp cách nhau 3 bytes
}//Xử lý xong 1 hàng
//Chuyển con trỏ xuông hàng kế tiếp
p += nOffset;
}
bm.UnLock(bmData);//giải phóng biến BitmapData
Đoạn lệnh trên sẽ biến bức ảnh thành màu trắng.
** Demo code:
Code kèm theo làm 2 thao tác ví dụ cho việc xử lý:
- Tăng màu của mỗi pixel ảnh lên 20 (menu Contrast - ko biết dùng từ này có đúng không,
dốt t.Anh quá42)
- Thực hiện lấy nghịch đảo 1 ảnh( phép toán NOT)

- Như các bạn đã biết
+ Một ảnh mức xám có nghĩa là: một điểm ảnh trong ảnh này được biểu diễn bằng một số
8 bit = 2^8=256 giá trị từ tối tới sáng
+ Một ảnh nhị phân: một điểm ảnh được biểu diễn bằng số một bit = 2^1=2 giá trị tối và
sáng
+ Ảnh màu đương nhiên được tổng hợp từ 3 màu R-G-B
Ví dụ:
- Để chuyển ảnh màu về ảnh xám chúng ta có công thức sau:
a. O(x,y)=( IR(x,y) + IG(x,y) + IB(x,y)) /3
Với:
x,y là tạo độ của điểm ảnh
IR thành phân màu đỏ tại màu I(x,y)
IG thành phân màu xanh lá tại màu I(x,y)
IB thành phân màu xanh dương tại màu I(x,y)
O(x,y): mà đầu ra, I(x,y) màu đầu vào
b. O(x,y)= IR(x,y) * 0.287 + IG(x,y) * 0.599 + IB(x,y) * 0.114
Ví dụ 1: Sử dụng công thức b cho ví dụ 1 như sau:
Code:

private Bitmap ToGray(Bitmap bm)
{
Bitmap bitmap = new Bitmap(bm);
int x, y;
Color c;
Byte gray;
for (y = 0; y < bm.Height - 1; y++)
{
for (x = 0; x < bm.Width - 1; x++)
{
c = bm.GetPixel(x, y);

}
return bitmap;
}
- Ở hàm trên nếu c.R < band chúng ta sử dụng là c.R vì đối với ảnh mức xám thì 3 thành
phần màu bằng nhau nên không cần phân biệt c.R, c.G hay C.B.
- Bạn hãy tạo 1 project rồi kiểm thử nó.
1.2 Sử dụng LockBits
- Nhìn lại ví dụ 2, chuyện gì đã xảy ra…: Chạy tốt, nhưng vấn đề là thời gian
- Hai hàm trên đều sử dụng 2 phương thức set và get, về mặt thuật toán có lẻ bạn nghĩ 2
vòng lặp đó đã làm cho chương trình trở nên quá rùa đồng thời nếu sử dụng ảnh có độ
phân giải hơi lớn tí là có thể treo luôn.
- Vấn đề không phải giải thuật mà chính do 2 phương thức set và getpixel gây nên, khi bạn
gọi 2 phương thức này hệ điều hành Win sẽ Lock ảnh lại đến khi kết thúc phương thức vừa
goi tự động sẽ UnLock ảnh đó cho việt truy cập lần sau. Chính việc Lock rồi Unlock liên
tục đã làm đã làm cho hàm trên xử lý chậm rãi từ tốn.
- Giải thuật sau dùng kỹ thuật LockBits
Code:

private Bitmap ToBinaryLocBits(Bitmap bm, Byte band)
{
Bitmap bitmap = new Bitmap(bm);
Rectangle rec = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
System.Drawing.Imaging.BitmapData bmpData = bitmap.LockBits(rec,
System.Drawing.Imaging.ImageLockMode.ReadWrite, bitmap.PixelFormat);
IntPtr ptr = bmpData.Scan0;
Int32 bytes = bmpData.Stride * bitmap.Height;
Byte[ rgbValues = new Byte[bytes - 1];
System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes);
Byte color;
for (int counter = 0; counter < rgbValues.Length - 1; counter += 4)


Nhờ tải bản gốc

Tài liệu, ebook tham khảo khác

Music ♫

Copyright: Tài liệu đại học © DMCA.com Protection Status