* Đọ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: Code:
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 Code:
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) Như vậy, mỗi hàng của bức ảnh sẽ dùng hết bm.Width*3 bytes để lưu thông tin (do mỗi pixel 3 byte) Tuy nhiên khi lưu vào máy, thì mỗi hàng của ảnh phải dùng nhiều hơn số byte đó để lưu, vì mục đích lưu cả thông tin của biên thì phải ( cái này sẽ xem thêm). Để biết thực sự số byte này là bao nhiêu, đầu tiên phải chuyển bm sang 1 lớp đệm, lớp BitmapData Ví du:

int nOffset = stride . vì nếu ta nghĩ ảnh kích thứơc 5x5. ta truy xuất vào byte thứ 16.ReadWrite. chính là kích thước của ảnh bm. x++) { //Xử lý 3 byte của pixel p[0] = 255. thì lưu trên đĩa 5x3=15 byte 1 hàng. . y++) { for(x = 0. p[1] = 255. sang 1 vùng nhớ (bmData). BitmapData bmData = bm. ImageLockMode.Height.y. nhưng nếu stride=16. trên đó có các thứ cần thiết để can thiệp vào từng điểm ảnh. khi con trỏ xử lý đến pixel cuối cùng của hàng. rồi dùng con trỏ trỏ đến địa chỉ đó. Bây giờ. Trên ảnh bm. Quan trọng. for(y = 0. Các bước đọc ảnh và hiển thị đã nói ở trên.24bitrgp). ** Ghép mấy thứ loằng ngoằng trên để xử lý 1 bức ảnh xem nào: Đặt ra 1 ví dụ: đọc 1 bức ảnh và hiện lên form.Width*3.Width. 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.Code: Rectangle rec = new Rectangle(0. int stride = bmData. bmData sẽ "trả công" cho ta bằng cách cung cấp cho ta 2 thuộc tính quan trọng: . // 2 pixel kế tiếp cách nhau 3 bytes }//Xử lý xong 1 hàng .Scan0: chú ý là số 0. Tư tưởng là vậy. //nOffset chính là cái rìa của bức ảnh. thay đổi. Muốn sửa.ReadWrite. ImageLockMode.Stride: số byte thực sự mà máy tính lưu trũ mỗi hàng của ảnh. và dùng làm tham số cho câu lệnh phía dưới.bm.Scan0.Height). Phương thức LockBits sẽ chuyển từ 1 ảnh. Code: BitmapData bmData = bm. khi người dùng nhấn vào 1 nút trên form.LockBits(rec.24bitrgp).bmData. thì khi ta muốn xuống dòng thứ 2 đễr xử lý tiếp.0. ta chỉ có thể xem nó. biến bức ảnh đó thành toàn màu trắng. p[2] = 255.LockBits(rec. Chú ý màu trắng là cả 3 byte của nó đều bằng 255. PixelFormat. PixelFormat. thì thực tế ta lại truy xuất vào cái rìa của dòng 1.Width. y<bm. không phải chữ O. thì muốn xuống //hàng kế tiếp. //p sẽ trỏ đến địa chỉ đẩu của ảnh int x. Cái này chỉ ra địa chỉ pixel đầu tiên của ảnh mà bmData quản lý. Muốn thay đổi từng pixel ta phải biết cái này.Stride. Ở đây ta chỉ quan tâm đến việc thay tất cả các pixel của ảnh thành pixel màu trắng.bm.bm. chứ không thể chỉnh sử pixel. tiếp tục thay đổi tiếp. phải chuyển nó sang lớp BitmapData. x<bm. //Chuyển con trỏ sang pixel kế tiếp p += 3. Câu lệnh đầu tiên khai báo 1 hình chữ nhật rec. sau đó dịch con trỏ lên 1 đơn vị.bmData.

2). PixelFormat.Width. green. BitmapData có những thuộc tính quan trọng như sau: • Scan0 Địa chỉ trong bộ nhớ của mảng dữ liệu • Width Độ rộng tấm ảnh ( số pixel) • Height Độ cao tấm ảnh • Stride Độ rộng theo byte của mỗi dòng.5) và tiếp tục.Tăng màu của mỗi pixel ảnh lên 20 (menu Contrast) . Để có thể xử lý bức ảnh.Height: độ cao của bức ảnh // PixelFormat.ReadWrite.UnLock(bmData). 0.//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.4.Height).LockBits(new Rectangle(0.Format24bppRgb). } bm. Cấu trúc của ảnh Bitmap: Ảnh Bitmap là một ma trận các pixel. pixel tiếp theo là (3. red ). ta cần phải tạo ra đối tượng BitmapData thông qua phương thức LockBits của đối tượng Bitmap như sau: CODE(Mã) BitmapData bmData = b. Tuy nhiên đối tượng Bitmap chỉ dùng để hiển thị bức ảnh. chẳng hạn như với ảnh 24 bits thì sẽ có 3 bytes dành cho mỗi pixel ( mỗi byte 1 màu ứng với blue. Các hàm này sẽ trả về giá trị true nếu lọc ảnh thành công và false nếu ngược lại. ảnh sẽ được xử lý trên chính đối tượng BitmapData này.Format24bppRgb: chỉ ra là ảnh 24 bits Có thể coi BitmapData là một vùng nhớ đệm lưu trữ dữ liệu của bức ảnh mà thông qua nó bạn có thể chỉnh sửa bức ảnh theo ý mình.cs.Width: độ rộng của bức ảnh // b. ** Demo code: Code kèm theo làm 2 thao tác ví dụ cho việc xử lý: . b. Chúng ta sẽ làm việc đối với các ảnh là Bitmap ( các ảnh thuộc các định dạng khác đều có thể dễ dàng chuyển về ảnh Bitmap) và một đối tượng quan trọng là BitmapData.1. là nơi chứa các hàm thực hiện các bộ lọc. luôn luôn lớn hơn Width • PixelFormat Định dạng chính xác của bức ảnh . Như vậy pixel đầu tiên sẽ chiếm 3 bytes đầu (0.//Chuyển con trỏ xuông hàng kế tiếp p += nOffset.Thực hiện lấy nghịch đảo 1 ảnh( phép toán NOT) Nội dung Nội dung chính của chuơng trình nằm trong file Filter. ImageLockMode. // b. b.

( phần thêm vào gọi là Padding. Stride như hình sau: Như trên hình vẽ. Ví dụ như một bức ảnh 24 bits có 17 pixel mỗi hàng thì sẽ có Stride = 52. trong đó used pixel data = 3*17 = 51 và 1 byte còn lại được thêm vào để được là 52 = 4*13.Mối quan hệ giữa Scan0.Width với ảnh 24 bits). Nguyên nhân là để tăng hiệu năng. tuy nhiên không phải lúc nào cũng chính xác bằng số pixel nhân với số byte mỗi pixel ( ví dụ 3 * b. hệ thống sẽ luôn mặc định để cho giá trị tính theo byte ở mỗi hàng chia hết cho 4. thuộc tính Stride mang giá trị là độ rộng của một hàng tính theo byte. hay Offset ) .

J3 7 7.2.94 497H31472.0 -2  7 85480 .

.

.39. J.2-90 :   509..23K3 94 O.33-J9 9.103  2.42E 9K23..97H3-H397E.:50 :9H3..K2..-.E38029H2   l-99.9393..3.0 -23.5O3-37. 23.:..9   l-93-2.9. 'J/: .9..-. 93503  :97.:.2-9095     .3.8..88-903-.9J3 -2 /985097H33 73  -2 0983 .2.50 3939.33.5.:3-28.E.7.:9393 /4250-90   %:3H3.7.59:.: .3 .35 2 592.38-90 O .35/33:.973.250-98-908 39..38/39-2 /9 -908 .43H: .4   .: .28.43H:  :9H35..:3.9.3  %7::9.5.9.8  E.-H39K5 .OJ. 9.

3.:35J.:97H3 .5.3970.9.33 -2.3 O 939432:973   E.9.4-909 9K9.9./790 !0472.39 3O97H3  9. 2.:9723..4/0 #0.9.49.  E3. 959.28.4..   F5294334397H3  -.3.439797 3 .3.. $.-90.9.J3J.5-9.9J36:.-903 3.98 70..9. O 9. 9K.30234  l97..-..6:3 :39.33 J.5.3592.9.6:.  8.E..3H31472 3./3  -2.E. 95 %..49.:3.39. 5. 8 35...9..   !.E7K.395.3..O. ....9..50 :9H3.4 .9.98 70.3850 :38. $97/0 393 11809897/0 -2 /9  .9..04.:33O8.-.4.99.50.9.3 93502:973  2:973. 93509.9:.3O :-3  4/0 92.3973 .3 .32-2.O9023O  .4397H3 .-2./329. $97/08-909.99. .43997H31472 -3-.988.3./333./790 !0472. %7H33-2 9.-3.E.:393 8.3973 -2. 2.97::9.30#0.5.39.-2 4.04.4/0 #0.392 3. ..2:3:3/39  7 95 9.9. 9..9 -975  39897/0-2.9.-E4K3./.9.822E9J3.E 3 7/3.9.493 23    -2.K3:9.9.3070.5.399 ..897.-2.9 -975  :3 :9H3. 97H3 O.9..J/ ..3 ":.: O/.3.33:897/0 9K9.3-2 .30 -2 /9 -2 09  92...-2 4.7.4/0 #0.97::9.

.

3 11809.3. 3 9K2:3:3 .-...:.4397  350.J3.3 ..E7K.

.

3-3.E..5-6:. $.39H2 .3  .E7K..4397. 3 11809  -90 5 -90 -2..9.395 9...

.

. :.5897 3 .3 39  147  -2 09   147  -2 /9   ..

.

50 5 ( 5( 5( . -90..

.

35095 5 .43978.:3.

.

5095.3.:-908 <.E.

.

 433 .

.

.

.4397:3395 5 3 11809 < -2 &34.:3.9. -2.

.

973.-2.98 30#0. .9.2-908 :   5095 904    .9 472.9...49E.O9//3.E..3  :97.  9.3-989K8. 39. .O-908/3.  %:3H3 9.5.803:3. E.4.1....397K332974310907 .  %g32:.E.39:.936:..30  - /9 - 09  2.39.5O3-392.397392.4/0 4/0G290429.959..3 9.392.3.:3.392.. 3/3E.4250  2-902:3.5..3 l. 23897.333.393.- 4.89  %.392.3.9.50 :9H38.-.J3 9.5.53.E.4..392.9..J3.9.5.33.. .50 .5 .29 9.-:0 7003 70/ .2503H3  203:4397.82.5 .8..O9 -..4/0 #0.8 3./790 !0472.5292.29...   l43397H38-3-.9.3932:973   024.5.E9797:03:.E.392.36:.35947. 43 5F594E3 %  /:3 /:3.9. 97H3.E.:       92.:. 38 . 9.E. :.J/.392..04.9-55#./3 39-.98.5..5.5 392.392.

.

.-.3 .- /9 73.

.

.4.-.- 09 ..3 .

.

5..3-98   O9.8.!0472.39733.7.9-55#-..O339:.J3E.32936:.-.3 8.9 472.3904 2K3  92.-...9743-3.492.9.O9.2/3 :3:33....9..-.3 l.3/9 W!0472.23/: W/9l73923 850  W09l.9J36:.:97/:..: W$.4923 W$97/0l73904-90.9l3/3.29.33 2.5.3O-3.3  .

97H3K3. 11809  ...3-98  :H333 9g3:3g3 938:32.J3E.4!.3 .29-.   539H2.:    .3.$.-90.J/ - /9.-385033. 3 .O$97/0 9743 O:80/50 /.8-90250 . .3 $97/03.9.O50239K8.4  ..4E979J3904-9023.3-98.//3  .. 9. 9:.K38.4 'J/3.34.9J3$97/02.2939J3904-90 9:3H33 5.3.6:.9H2.3E97 73..