Ngày đăng: 17/08/2012, 07:05
Xây dựng chương trình vẽ hình giống microsoft paint Lời giới thiệu Đồ họa lập trình ln chủ đề yêu thích lập trình viên chế đồ họa lập trình viên thỏa mãn khiếu họa sĩ khả lập trình thân Khi thiết kế chương trình đồ họa lập trình viên thỏa sức tưởng tượng nghiên cứu tìm tịi để chương trình thực theo tưởng tượng Ngồi với ứng dụng rộng rãi đời sống (ngành game, truyền thông đa phương tiện, ngành quảng cáo…) đồ họa cịn nghề “hái tiền” công nghệ thơng tin Đề tài em lập trình chương trình tương tự Microsoft Paint Windows chương trình đồ họa đơn giản quen thuộc hệ điều hành Windows Với giới hạn ngơn ngữ lập trình C/C++ khả thân, em cố gắng thiết kế chương trình có giao diện chế làm việc gần giống MS Paint Em xin chân thành cảm ơn Thầy hướng dẫn Đinh Tuấn Long hướng dẫn em thực tập lớn tốt nghiệp X©y dựng chơng trình vẽ hình giống microsoft paint Phn I : Đặt vấn đề 1 Mơ tả tốn : Sử dụng chế độ đồ họa C/C++ số thuật tốn cần thiết để lập trình xây dựng chương trình vẽ hình giống Microsoft Paint : Chương trình có giao diện gần giống MS Paint thao tác sử dụng tương tự gồm có: - bảng chứa chức vẽ - bảng chứa danh sách màu vẽ (gồm 16 màu bản) - Phần hình dùng để vẽ hình - Sử dụng chuột để chọn màu vẽ chức vẽ vẽ hình đồ họa - Các chức tạo mới, save, load, trợ giúp, thoát Yêu cầu chương trình : - Thiết kế giao diện tương tự MS Paint với phần - Làm việc với 16 màu - Sử dụng chuột để vẽ - Có cơng cụ : bút vẽ, vẽ đường thẳng, vẽ hình chữ nhật, vẽ hình vng, vẽ hình đa giác, vẽ hình ellip, vẽ hình trịn, vẽ hình đặc, xóa tơ màu miền kín thiết kế bảng chứa chức vẽ dạng ô công cụ để lựa chọn chuột - Có chức ghi ảnh vẽ mở file ảnh để thực việc vẽ tiếp - Có chức tạo mới, trợ giúp, thoát để điều khiển chương trình - Tất điều khiển sử dụng chuột ( Khởi tạo điều khiển chuột sử dụng ngắt chuột (0x33) ) Phần II : Giải vấn đề Ngôn ngữ thực : C/C++ Các vấn đề phương án giải : a) Khởi tạo điều khiển chuột : Bằng cách tác động vào ghi _AX,_BX,_CX,_DX ngắt chuột geninterrupt(0x33) để khởi tạo điều khiển thao tác chuột: - Khởi tạo : int kt_mouse() { _AX = 0; geninterrupt(0x33); if (_AX == 0) return _AX; else return _BX; } - Ẩn ,hiện chuột : void hien_mouse() { _AX = 1; geninterrupt(0x33); } void an_mouse() { _AX = 2; geninterrupt(0x33); } - Khai báo biến trỏ để lấy vị trí chuột : void mouse_getXY(int *mouseX, int *mouseY) { _AX = 3; geninterrupt(0x33); *mouseX = _CX; *mouseY = _DX; } - Kiểm sốt việc kích chuột nhả chuột : int kich_mouse_trai() { _AX = 3; geninterrupt(0x33); return (_BX>>0)&1; } int kich_mouse_phai() { _AX = 3; geninterrupt(0x33); return (_BX>>1)&1; } int nha_mouse_trai() { int fx, fy, lx, ly; _BX = 0; _AX = 6; geninterrupt(0x33); if (_BX == 1) { fx = _CX; fy = _DX; mouse_getXY(&lx, &ly); if ((fx == lx)&(fy == ly)) return 1; else return 0; } else return 0; } int nha_mouse_phai() { int fx, fy, lx, ly; _BX = 1; _AX = 6; geninterrupt(0x33); if (_BX == 1) { fx = _CX; fy = _DX; mouse_getXY(&lx, &ly); if ((fx == lx)&(fy == ly)) return 1; else return 0; } else return 0; } - Kiểm soát việc di chuyển chuột: void mouse_move(int mouseX, int mouseY) { _AX = 4; _CX = mouseX; _DX = mouseY; geninterrupt(0x33); } void mouse_setX(int start, int end) { _AX = 7; _CX = start; _DX = end; geninterrupt(0x33); } void mouse_setY(int start, int end) { _AX = 8; _CX = start; _DX = end; geninterrupt(0x33); } b) Trong chế độ đồ họa MS Paint đường thẳng, hình chữ nhật đường ellip vẽ theo cách dùng chuột xác định điểm : - Đối với đường thẳng điểm : điểm đầu điểm cuối - Đối với hình chữ nhật điểm xác định đường chéo - Đối với hình ellip điểm xác định đường chéo hình chữ nhật ngoại tiếp hình ellip Trong chương trình mô MS Paint em xác định điểm để lập trình vẽ đường thẳng, hình chữ nhật hình ellip (dựa theo việc thay đổi trục x, y ta vẽ hình vng hình trịn từ hình chữ nhật hình ellip) Để lập trình chương trình tương tự MS Paint (khi xác định điểm cuối cách di chuột hình vẽ biến đổi theo vị trí chuột ) em xây dựng thêm hàm lineMY ,rectMY ,ellipMY để vẽ hình putpixel() điểm hình đồ họa (riêng hàm ellipMY hỗ trợ hàm doixung() để vẽ đối xứng cung tròn) void lineMY(int sx, int sy, int ex, int ey, int c, int style ) { int t, d; int xe = 0, ye = 0, dx, dy; int ix,iy; dx = ex - sx; dy = ey - sy; if (dx > 0) ix = 1; else if (dx == 0) ix = 0; else ix = -1; if (dy > 0) iy = 1; else if (dy == 0) iy = 0; else iy = -1; dx = abs(dx); dy = abs(dy); d = (dx > dy) ? dx : dy; for (t = 0; t <= d; t++) { if (style == 1) putpixel(sx, sy, c^getpixel(sx, sy)); else putpixel(sx, sy, c); xe = xe + dx; ye = ye + dy; if (xe > d) { xe = xe - d; sx = sx + ix; } if (ye > d) { ye = ye - d; sy = sy + iy; } } } void rectMY(int sx, int sy, int ex, int ey, int c, int style) { lineMY(sx, sy, ex, sy, c, style); lineMY(sx, sy, sx, ey, c, style); lineMY(ex, sy, ex, ey, c, style); lineMY(sx, ey, ex, ey, c, style); if (style == 1) putpixel(ex, ey, c^getpixel(ex, ey)); else putpixel(ex, ey, c); } void doixung(int xc, int yc, int style) { if (style == 1) { putpixel(xc + xp, yc xp, yc - yp)); putpixel(xc + xp, yc + xp, yc + yp)); putpixel(xc - xp, yc + xp, yc + yp)); putpixel(xc - xp, yc xp, yc - yp)); } else { putpixel(xc + xp, yc putpixel(xc + xp, yc + xp, int yp, int c, int yp, c^getpixel(xc + yp, c^getpixel(xc + yp, c^getpixel(xc yp, c^getpixel(xc - yp, c); yp, c); putpixel(xc - xp, yc + yp, c); putpixel(xc - xp, yc - yp, c); } } void ellipMY(long xc, long yc, long a, long b, long c, int style) { long xp, yp, vung = 1; double d = b*b - a*a*b + ((float)a*a/4); xp = 0; yp = b; while (yp >= 0) { doixung(xc, yc, xp, yp, c, style); if ((vung ==1) & (a*a*(yp - 0.5) <= b*b*(xp + 1) )) { vung = 2; d = b*b*xp*xp+b*b*xp + ((float)b*b/4) + a*a*(yp-1)*(yp -1) - a*a*b*b; } if (vung ==1) { if (d < 0) { d = d + b*b*(2*xp + 3); xp = xp + 1; } else { d = d + b*b*(2*xp + 3) + a*a*(2-2*yp); xp = xp + 1; yp = yp -1; } } if (vung == 2) { if (d < 0) { d = d + b*b*(2*xp+2)+a*a*(3-2*yp); xp = xp + 1; yp = yp -1; } else { d = d + a*a*(3-2*yp); yp = yp -1; } } } } c) Đối với hàm bút vẽ (draw_pen(int d)), hàm tẩy xóa(erase(int d)) có khai báo biến d để xác định độ dày nét vẽ Khai báo cấu trúc line_def để lưu lại kiểu đường mặc định : struct line_def { int linestyle; unsigned int upattern; int thickness; }; line_def(norm_line); Thiết lập kiểu mới: setlinestyle(SOLID_LINE,0,d); Phục hồi kiểu cũ: setlinestyle(norm_line.linestyle,norm_line.upattern ,norm_line.thickness); d) Hàm vẽ chấm điểm ngẫu nhiên vùng bán kính r (draw_air(int r)) dùng để tơ màu dạng airbrush: for (i = 0; i<= 5; ++i) { x = random(r + 1); if (random(2)) x = -x; y = random(int(sqrt(r * r - x * x))); if (random(2)) y = -y; an_mouse(); if ((nowX+x>frameX)&(nowX+xfra meY)&(nowY+y=bclick.x)&(nowX<=bclick.x+bclick.w) & (nowY>=bclick.y)&(nowY<=bclick.y+bclick.h)); } h) Một loạt hàm update (update_pcolor(), update_ bline(), update_bpen(), update_brect(), update_brectf(), update_bellip(), update_bellipf(), update_bpoly(), update_bair(), update_bera(), update_bfill(), update_nut()) sử dụng để vẽ hình mơ tả nút điều khiển i) Hàm kt_bangmau() khởi tạo vẽ hình bảng 16 mầu chia làm dòng : { int i; pcolor[0].b = 2; pcolor[0].h = 12;pcolor[0].stats = 1; pcolor[0].w = 36; pcolor[0].cap = ""; pcolor[0].x = 90; pcolor[0].y = 435; show_nut(pcolor[0]); setfillstyle(1, 0); bar(pcolor[0].x,pcolor[0].y,pcolor[0].x + pcolor[0].w, pcolor[0].y + pcolor[0].h); for (i = 1; i<= 7; i++) 11 { pcolor[i].b = 2; pcolor[i].h = 12;pcolor[i].stats = 1; pcolor[i].w = 36;pcolor[i].cap = ""; pcolor[i].x = pcolor[i-1].x + 40;pcolor[i].y = 435; if (i == ncolor) pcolor[i].stats = 0; show_nut(pcolor[i]); setfillstyle(1, i); bar(pcolor[i].x,pcolor[i].y,pcolor[i].x + pcolor[i].w, pcolor[i].y + pcolor[i].h); } pcolor[8].b = 2; pcolor[8].h = 12;pcolor[8].stats = 1; pcolor[8].w = 36; pcolor[8].cap = ""; pcolor[8].x = 90; pcolor[8].y = 435+20; show_nut(pcolor[8]); setfillstyle(1, 8); bar(pcolor[8].x,pcolor[8].y,pcolor[8].x + pcolor[8].w, pcolor[8].y + pcolor[8].h); for (i = 9; i<= 15; i++) { pcolor[i].b = 2; pcolor[i].h = 12;pcolor[i].stats = 1; pcolor[i].w = 36; pcolor[i].cap = ""; pcolor[i].x = pcolor[i-1].x + 40;pcolor[i].y = 435+20; if (i == ncolor) pcolor[i].stats = 0; show_nut(pcolor[i]); setfillstyle(1, i); bar(pcolor[i].x,pcolor[i].y,pcolor[i].x + pcolor[i].w, pcolor[i].y + pcolor[i].h); } } j) Hàm hien_color() có khai báo biến s để lưu giá trịmàu thời ô cstyle[s] { 12 cstyle[s].b = 2; cstyle[s].h = 34; cstyle[s].w = 34; cstyle[s].cap = ""; cstyle[s].x = 35; cstyle[s].y = 435; show_nut(cstyle[s]); setfillstyle(1, s); bar(cstyle[s].x,cstyle[s].y,cstyle[s].x + cstyle[s].w, cstyle[s].y + cstyle[s].h); } k) Hàm kt_bangve vẽ lên hình bảng chứa nút chức vẽ nút điều khiển chương trình: { panel.x = 10; panel.y = 50; panel.h = 130; panel.w = 55; panel.stats = 1; panel.cap = ""; panel.b = 1; pstyle.x = 15; pstyle.y = 190; pstyle.h = 30; pstyle.w = 45; pstyle.stats = 1; pstyle.cap = ""; pstyle.b = 1; bline.x = 15; bline.y = 55; bline.h = 20; bline.w = 20; bline.stats = 1; bline.cap = ""; bline.b = 1; bpen.x = 40; bpen.y = 55; bpen.h = 20; bpen.w = 20; bpen.stats = 1; bpen.cap = ""; bpen.b = 1; bellip.x = 15; bellip.y = 80; bellip.h = 20; bellip.w = 20; bellip.stats = 1; bellip.cap = ""; bellip.b = 1; brect.x = 40; brect.y = 80; brect.h = 20; brect.w = 20; brect.stats = 1; brect.cap = ""; brect.b = 1; 13 bellipf.x = 15; bellipf.y = 105; bellipf.h = 20; bellipf.w = 20; bellipf.stats = 1; bellipf.cap = ""; bellipf.b = 1; brectf.x = 40; brectf.y = 105; brectf.h = 20; brectf.w = 20; brectf.stats = 1; brectf.cap = ""; brectf.b = 1; bpoly.x = 15; bpoly.y = 130; bpoly.h = 20; bpoly.w = 20; bpoly.stats = 1; bpoly.cap = ""; bpoly.b = 1; bair.x = 40; bair.y = 130; bair.h = 20; bair.w = 20; bair.stats = 1; bair.cap = ""; bair.b = 1; bera.x = 15; bera.y = 155; bera.h = 20; bera.w = 20; bera.stats = 1; bera.cap = ""; bera.b = 1; bfill.x = 40; bfill.y = 155; bfill.h = 20; bfill.w = 20; bfill.stats = 1; bfill.cap = ""; bfill.b = 1; bnew.x = 15; bnew.y = 240; bnew.h = 20; bnew.w = 50; bnew.cap = "New"; bnew.stats = 1; bnew.b = 1; bsave.x = 15; bsave.y = 270; bsave.h = 20; bsave.w = 50; bsave.cap = "Save"; bsave.stats = 1; bsave.b = 1; bload.x = 15; bload.y = 300; bload.h = 20; bload.w = 50; 14 bload.cap = "Load"; bload.stats = 1; bload.b = 1; bhelp.x = 15; bhelp.y = 330; bhelp.h = 20; bhelp.w = 50; bhelp.cap = "Help"; bhelp.stats = 1; bhelp.b = 1; bexit.x = 15; bexit.y = 360; bexit.h = 20; bexit.w = 50; bexit.cap = "Exit"; bexit.stats = 1; bexit.b = 1; show_nut(panel); show_nut(pstyle); update_bline(); update_bpen(); update_brect(); update_bellip(); update_bellipf(); update_brectf(); update_bair(); update_bpoly(); update_bera(); update_bfill(); update_nut(bnew); update_nut(bsave); update_nut(bload); update_nut(bhelp); update_nut(bexit); } Hàm update_bstyle(int style) khai báo biến style với giá trị từ 1-10 dùng để mô tả công cụ vẽ thời: switch (style) { case 1:{ moveto(pstyle.x + 24, pstyle.y + 3); lineto(pstyle.x + 13, pstyle y + 14); l) 15 lineto(pstyle.x + 13, pstyle.y + 17); lineto(pstyle.x + 16, pstyle.y + 17); lineto(pstyle.x + 27, pstyle y + 6); lineto(pstyle.x + 24, pstyle.y + 3); line(pstyle.x + 22, pstyle.y + 5, pstyle.x + 25, pstyle.y + 8); line(pstyle.x + 13, pstyle.y + 14, pstyle.x + 16, pstyle.y + 17); line(pstyle.x + 8,pstyle.y + 20,pstyle.x + 37,pstyle.y + 20); break;} case 2:{ moveto(pstyle.x + 24, pstyle.y + 3); lineto(pstyle.x + 13, pstyle y + 14); lineto(pstyle.x + 13, pstyle.y + 17); lineto(pstyle.x + 16, pstyle.y + 17); lineto(pstyle.x + 27, pstyle y + 6); lineto(pstyle.x + 24, pstyle.y + 3); line(pstyle.x + 22, pstyle.y + 5, pstyle.x + 25, pstyle.y + 8); line(pstyle.x + 13, pstyle.y + 14, pstyle.x + 16, pstyle.y + 17); moveto(pstyle.x + 13, pstyle.y + 20); lineto(pstyle.x + 18, pstyle.y + 22);lineto(pstyle.x + 22, pstyle.y + 20); lineto(pstyle.x + 26, pstyle.y + 16);lineto(pstyle.x + 37, pstyle.y + 18); break;} case 3:{ ellipse(pstyle.x + 24,pstyle.y + 14,0,360,15,6); break;} case 4:{ 16 rectangle(pstyle.x + 12,pstyle.y + 5,pstyle.x + 33,pstyle.y + 20); break;} case 5:{ for (int j = 1;j<=30;j++) {ellipse(pstyle.x + 24,pstyle.y + 14,0,360,j/2,6);} line(pstyle.x + 24 ,pstyle.y + ,pstyle.x + 24 ,pstyle.y + 20); break;} case 6:{ for (int i = 1;i<=16;i++) {line(pstyle.x + 12,pstyle.y + + i,pstyle.x + 33,pstyle.y + + i);} break;} case 7:{ moveto(pstyle.x + 24, pstyle.y + 3); lineto(pstyle.x + 13, pstyle y + 14); lineto(pstyle.x + 13, pstyle.y + 17); lineto(pstyle.x + 16, pstyle.y + 17); lineto(pstyle.x + 27, pstyle y + 6); lineto(pstyle.x + 24, pstyle.y + 3); line(pstyle.x + 22, pstyle.y + 5, pstyle.x + 25, pstyle.y + 8); line(pstyle.x + 13, pstyle.y + 14, pstyle.x + 16, pstyle.y + 17); pstyle.x pstyle.x pstyle.x pstyle.x line(pstyle.x + 13, pstyle.y + 13, pstyle.y + 25); line(pstyle.x + 13, pstyle.y + 33, pstyle.y + 25); line(pstyle.x + 33, pstyle.y + 39, pstyle.y + 8); line(pstyle.x + 39, pstyle.y + 13, pstyle.y + 20); + 20, + 25, + 25, + , 17 break;} case 8:{ int i, r = ,x, y; for (i = 0; i<= 25; i++) { x = random(r + 1); if (random(2)) x = -x; y = random(int(sqrt(r*r - x * x))); if (random(2)) y = -y; an_mouse(); putpixel(pstyle.x + x + 22, pstyle.y + y + 15, 1); hien_mouse(); } break;} case 9:{ bar3d(pstyle.x + 12, pstyle.y + 15, pstyle.x + 20, pstyle.y + 20, 10, 5); break;} case 10:{ rectangle(pstyle.x + 20, pstyle.y + 1, pstyle.x + 24, pstyle.y + 6); line(pstyle.x + 24, pstyle.y + 6, pstyle.x + 28, pstyle.y + 10); line(pstyle.x + 20, pstyle.y + 6, pstyle.x + 16, pstyle.y + 10); rectangle(pstyle.x + 12, pstyle.y + 10, pstyle.x + 32, pstyle.y + 22); int i; for (i = 1;i<=5;i++) { line(pstyle.x + 12 + 2/i, pstyle.y + 12, pstyle.x + 14 + 18/i, pstyle.y + 22);} break;} } 18 Mô tả chức : Hàm main() khởi tạo thứ : void main() { kt_dohoa(); kt_mouse(); kt_bangve(); kt_mhve(); kt_bangmau(); hien_color(15); hien_mouse(); run_run_run(); closegraph(); } Sau khởi tạo xong chương trình gọi đến hàm run_run_run() để bắt đầu chạy chương trình Hàm run_run_run() chạy liên tục finish = kết thúc nút Exit kích hoạt finish =1 Kiểm tra chuột: - Nếu kich_mouse_trai() chương trình lấy vị trí kích mouse (mouse_getXY(&nowX, &nowY);) so sánh với vị trí nút hình thay đổi stats nút đó(để nút thành “ẩn”) đồng thời loại nút vẽ lên bstyle - Khi nha_mouse_trai() chương trình xác định click mouse màu vẽ chuyển màu thành màu thời cịn click mouse chức vẽ gọi hàm tương ứng thực chức vẽ - Các ô chức New, Save, Load, Help thực giống ô chức vẽ Khi nút Exit kích hoạt, finish = chế độ đồ họa kết thúc chương trình gọi hàm closegraph() để đóng chế độ đồ họa trở mode văn 19 Giao diện cách sử dụng : Màn hình đồ họa chương trình gồm phần : - Bảng chứa ô chức vẽ - Bảng chứa ô màu vẽ (16 màu) - Các nút New, Save, Load, Help, Exit - Màn hình vẽ Sau khởi tạo chương trình người dùng sử dụng chuột để thao tác điều khiển hình chương trình Đầu tiên khởi tạo hình vẽ có màu đen ô màu vẽ mặc định màu trắng, người dùng chọn màu vẽ chọn công cụ vẽ bảng chức Chọn xong, chương trình đưa chuột đến trung tâm hình vẽ để người dùng đồ họa trỏ chuột di chuyển khung hình vẽ mà thơi Để khỏi chế độ vẽ thời để chọn màu vẽ khác cơng cụ vẽ khác người dùng phải click chuột phải Q trình ln tiếp diễn người dùng chọn nút Exit khỏi chương trình 20 Lời kết Chương trình em mơ gần giống giao diện phương thức làm việc phần mềm MS Paint Windows : hình đồ họa chia thành nhiều phần , có giao diện điều khiển dùng chuột khả vẽ hình bản… Nhưng thiếu sót chương trình cịn nhiều : chế tơ màu cịn q sơ sài, chế save ảnh load ảnh khơng hồn thiện…Một phần thời gian cấp bách (1 tháng chuẩn bị) với khả thân em có giới hạn nên chương trình cịn nhiều sai sót Vì em mong nhận nhiều ý kiến đóng góp Thầy ý kiến phản hồi bạn để em rút kinh nghiệm hồn thành chương trình Một lần em xin chân thành cảm ơn 21 Tài liệu tham khảo Giáo trình ngơn ngữ lập trình Khoa cơng nghệ tin học Viện Đại học Mở Hà nội C++ & Lập trình hướng đối tượng GS.TS Phạm Văn Ất Nhà xuất khoa học kĩ thuật – 2006 Các giáo trình sách điện tử mạng Internet 22 Mục lục Lời giới thiệu Phần : Đặt vấn đề .2 Mơ tả tốn 2.Yêu cầu chương trình Phần : Giải vấn đề Ngôn ngữ thực .3 Các vấn đề phương án giải 3 Mơ tả chức 19 Giao diện cách sử dụng 20 Lời kết .21 Tài liệu tham khảo 22 Mục lục .23 23 ... lập trình xây dựng chương trình vẽ hình giống Microsoft Paint : Chương trình có giao diện gần giống MS Paint thao tác sử dụng tương tự gồm có: - bảng chứa chức vẽ - bảng chứa danh sách màu vẽ. .. chuột để vẽ - Có cơng cụ : bút vẽ, vẽ đường thẳng, vẽ hình chữ nhật, vẽ hình vng, vẽ hình đa giác, vẽ hình ellip, vẽ hình trịn, vẽ hình đặc, xóa tơ màu miền kín thiết kế bảng chứa chức vẽ dạng... x, y ta vẽ hình vng hình trịn từ hình chữ nhật hình ellip) Để lập trình chương trình tương tự MS Paint (khi xác định điểm cuối cách di chuột hình vẽ biến đổi theo vị trí chuột ) em xây dựng thêm
Xem thêm:
Xây dựng chương trình vẽ hình giống microsoft paint, Xây dựng chương trình vẽ hình giống microsoft paint