Võ Văn Hải's blog

Chỉ có một điều tuyệt đối đó là mọi thứ đều tương đối…

Ứng dụng duyệt hình ảnh với C#

Trong ví dụ này tôi muốn chỉ cho các bạn:

  1. Cách xây dựng một cây thư mục các ổ đĩa
  2. Trình duyệt ảnh

Xây dựng cây thư mục:

public void BuildTree()

{

string[] drives = Directory.GetLogicalDrives();

TreeNode node = null;

foreach (string drv in drives)

{

node = new TreeNode(drv);

folderTreeView.Nodes.Add(node);

node.Nodes.Add(“TempForExpandedEvent”);//dùng để cho phép mở sau đó gọi sự kiện before expanded

}

}

Hàm này sẽ nạp các ổ đĩa của hệ thống và một “nút nhử” để có thể khi mở rộng node thì sẽ load danh sách các thư mục con. Ở đây chúng ta không xây dựng sẵn cây thư mục mà chỉ load những thư mục cần thiết mà thôi.

Nếu các bạn muốn xây dựng cây thư mục sẵn thì phương thức sau sẽ làm được điều đó. Tuy nhiên tốc độ rất chậm và chiếm nhiều bộ nhớ do chương trình phải xây dựng toàn bộ cấu trúc cây thư mục của tất cả các ổ đĩa

private void ExploreDirectory(DirectoryInfo dir,TreeNode node)

{

DirectoryInfo[] directories = dir.GetDirectories();

foreach (DirectoryInfo newDir in directories)

{

TreeNode x = new TreeNode(newDir.Name);

node.Nodes.Add(x);

try{

ExploreDirectory(newDir, x);

}

catch (Exception){}

}

}

Như vậy, khi mở một thư mục nào đó, chương trình sẽ nạp tiếp cấp của thư mục được chọn mà thôi:

private void folderTreeView_BeforeExpand(object sender, TreeViewCancelEventArgs e)

{

TreeNode node = e.Node;

node.Nodes.Clear();

Adddir(node);

}

void Adddir(TreeNode node)

{

string path = node.FullPath;

try

{

foreach (string dir in Directory.GetDirectories(path))

{

TreeNode n = node.Nodes.Add(Path.GetFileName(dir));

n.Nodes.Add(“TempForExpandedEvent”);

}

}

catch { }

}

Cứ tiếp tục như vậy ta sẽ xây dựng được 1 cây thư mục “open on demand”.

Trình duyệt ảnh

Ta sử dụng control FlowLayerPanel để nạp tất cả các hình ảnh có trong thư mục đang chọn. Ta sử dụng control này là bởi vì nó cho phép các control khác được thêm vào theo nguyên tắc Flowlayout.

/// <summary>

/// Nạp các hình ảnh từ 1 thư mục lên FlowLayerPanel

/// </summary>

/// <param name=”path”>đường dẫn thư mục cần load</param>

private void LoadImage(string path)

{

thumbnailsFLP.Controls.Clear();

displayPictureBox.Image = null;

string[] Files = Directory.GetFiles(path);

thumbnailsFLP.Controls.Clear();

int i=1;

foreach (String fn in Files)

{

//FileInfo f = new FileInfo(path + “\\” + fn);

if (fn.ToLower().EndsWith(“.jpg”) || fn.ToLower().EndsWith(“.GIF”) ||

fn.ToLower().EndsWith(“.png”) || fn.ToLower().EndsWith(“.bmp”) ||

fn.ToLower().EndsWith(“.jpeg”))

{

PictureBox pic = new PictureBox();

pic.SizeMode = PictureBoxSizeMode.StretchImage;

pic.Image = Image.FromFile(fn);

pic.Height = 120;

pic.Width = 80;

pic.Cursor = Cursors.Hand;

thumbnailsFLP.Controls.Add(pic);

pic.Click += new EventHandler(pic_Click);

}

if(i++==10)

Application.DoEvents();

}

}

void pic_Click(object sender, EventArgs e)

{

PictureBox pic = (PictureBox)sender;

displayPictureBox.Image = pic.Image;

}

Hình ảnh khi chạy:

IThumbails

Và sau đây là code hoàn chỉnh ImagesThmbnails

Chúc may mắn

58 Responses to “Ứng dụng duyệt hình ảnh với C#”

  1. Phạm Văn Thứ said

    Em chào thầy,em là học sinh lớp ncth1a.Em lập trình hơi kém, thầy có thể cho em biết dùng phần mềm nào để viết C# không ạ,Em cảm Ơn thầy trước

  2. Bạn Thứ có thể sử dụng visual studio 2005 hoặc 2008 để viết C#

  3. Hi Thầy!
    Cái này mình làm trên Application còn nếu làm theo kiểu web của trang này thì làm thế nào vậy: http://www.camon.com.vn/

  4. vovanhai said

    Web Form phải viết khác đi chứ bạn. Bạn có thể làm bằng nhiều cách, chẳng hạn dễ nhất thì bạn dùng tag table, trong mỗi ô bạn dùng thẻ img để hiển thị hình.
    Chúc vui!

  5. Hồng Đức said

    Chào thầy.
    Em đang làm đồ án có liên quan đến việc phân đoạn ảnh, và em định sử dụng ngôn ngữ C# để viết chương trình. Thầy có thể cho em biết trong C# có các hàm nào liên quan đến việc xử lý hình ảnh.

  6. vovanhai said

    Em phải dùng GDI+, DirectX SDK để lập trình xử lý hình ảnh. Em có thể download nó tại trang web của microsoft.
    Chúc vui!

  7. Hồng Đức said

    Thầy cho em hỏi, ta cần sử dụng hàm nào để có thể lấy ra một điểm ảnh xem nó có giá trị màu nào.

  8. PHUNH said

    Thưa thầy, thầy có thể gửi cho em source code của Ví dụ này được không ạh!
    Link trên bị hỏng rồi ạh!
    Em cảm ơn thầy!

  9. PHUNH said

    Thưa thầy, thầy có thể gửi cho em source code của Ví dụ này được không ạh!
    Link trên bị hỏng rồi ạh!
    Đây là email của em: HeavenWind89@gmail.com
    Em cảm ơn thầy!

  10. ninjavn said

    Em chào thầy.
    Em đang làm một chương trình xử lý ảnh nhỏ nhỏ mà em không biết zoom image theo kiểu raster như thế nào cho nhanh (không bị giật).
    Mong thầy chỉ giúp.

    Em cảm ơn thầy.

  11. Trần đăng said

    mình cũng làm theo đoạn code trên của thầy hải.
    Nhưng đối với những folder mà có nhiều ảnh thì chương trình sẽ bị lỗi “out of memory” và treo máy luôn.
    Không biết thầy hải đã test đoạn code này hay chưa để khắc phục lỗi đó nữa.
    Do không biết email của thầy nên mong thầy hãy hồi âm cho em qua email:dangth.uit@gmail.com
    Cảm ơn thầy nhiều

  12. Minh Tân said

    Chào thầy..
    Em xin được phép copy phần hướng dẫn tạo cây thư mục của thầy, để chia sẻ cho các bạn.. ^_^ vẫn giữ nguyên tác .
    Em xin cảm ơn

  13. vovanhai said

    you are welcome,

  14. vovanhai said

    Để mình test lại. Có lẽ là vậy!

  15. Germaniteen said

    Em chưa hiểu dòng này lắm:
    n.Nodes.Add(“TempForExpandedEvent”);
    xin thầy chỉ thêm

  16. phuo said

    Thầy chỉ cho em cách duyệt cây thư mục để lấy toàn bộ file trong cây thư mục đó được không thầy. Em đang làm đề tài cần gấp lắm.

  17. vovanhai said

    Tức là em thêm 1 nút gọi là “nút mồi” làm cho nút đó có nút con để mà còn gọi được sự kiện _BeforeExpand. Nếu không có nó có nghĩa là nút không có nút con thì sự kiện này không xảy ra.
    Thêm vao đó, bạn không cần phải duyệt toàn bộ cấu trúc cây thư mục(tốn time) mà chỉ duyệt một cấp mà thôi. Chừng nào user muốn mở rộng cái nào ta chỉ cần nạp tiếp thư mục đó mà thôi!
    Chúc vui!

  18. vovanhai said

    Đây là method dùng đệ qui để duyệt cây thư mục:
    void ExploreDirectory(DirectoryInfo dir,TreeNode node)
    {
    DirectoryInfo[] directories = dir.GetDirectories();
    foreach (DirectoryInfo newDir in directories)
    {
    TreeNode x = new TreeNode(newDir.Name);
    node.Nodes.Add(x);
    try{
    ExploreDirectory(newDir, x);
    }
    catch (Exception){}
    }
    }

  19. cuongnv said

    Em chào thầy ạ. em đang tìm hiểu về C#, chủ yếu là lỹ thuật thao tác với file ảnh. Thầy có thể cho em xin tài liệu và các làm modul đọc bài thi trắc nghiệm trên giấy qua file ảnh được không ạ. Em xin chân thành cảm ơn!
    Email; cuongit4b@gmail.com

  20. long nguyen said

    Thầy cho em vấn đề này e đang gặp trục trặc.

    E đang làm một chương trình tính tiền bàn bida. E muốn load hình ảnh của số bàn mà e có trong cơ sở dữ liệu lên form thì e làm cách nào được ah. Cụ thể e có 7 bàn trong database , e muốn dùng 1 vòng lặp để load từ database số bàn mà e có lên trên form ,theo số thứ tự và tên đã có trong database. thầy có thể hướng dẫn cho e dc ko ạ

  21. vovanhai said

    Em tham khảo ở bài viết “Lưu hình ảnh vào database

  22. Tran Minh Thuan said

    Minh co tham khao chuong trinh cua Thay.

    Minh thay cach su dung node ao TempForExpandedEvent de nap cay thu muc cung kha hay, nhung co 1 van de la thu muc trong no cung hien nut dau + o do. Chi khi nao bam vao moi biet la no trong u?

    Minh co 1 cach la su dung de quy de mo rong cay. Ban khong can mo rong den nut cuoi cung, ma ban co the mo rong o level 1, 2 gi do, tinh tu nut hien tai. Nhu vay, qua trinh load cung nhanh, va dam bao tinh chan thuc cua dau +

  23. vovanhai said

    Cám ơn bạn. Bạn có thể post code lên cho mọi người cùng tham khảo.

  24. Le Xuan Hung said

    Cac ban oi cho tui hoi cai nay voi:
    Tui dang dinh lam mot phan mem de ngan chan cac web den dua vao tu khoa cho truoc va lap trinh dua vao viec phan tich goi tin winpcap su dung voi ngon ngu .Netframework, nhung tui van chua biet lam the nao ca. Co ai biet khong chi cho tui voi! Cam on nhieu!

  25. duytung said

    thua thay,e dang lam bai tap ve xu ly anh viet bang VS C#,e muon xu ly anh nhu la lam xam mau anh hang loat trong 1 folder,e chi xu ly duoc tung anh mot,mong thay giup do,thanks

  26. vovanhai said

    Thì em duyệt qua tất cả các hình trong thư mục, xử lý từng ảnh.

  27. duytung said

    cam on thay nhung y cua e la gia su trong thu muc do co 10 anh,khi minh chon chuc nang lam xam anh thi minh chon folder do,minh thuc hien chuc nang lam xam anh,thi ca 10 anh trong folder do deu xam mau,co nghia la no xu ly hang loat ko xu ly tung cai mot.trong C# co thuc hien duoc chuc nang do ko thay?neu co thay co the cho e thuat toan duoc ko a.thanks thay

  28. Duc Khiet said

    Thua thay! Em muon viet doan code de luu mot file anh xuong sql server (ko phai duong dan) phai viet nhu the nao vay thay… Xin thay chi em

  29. Trí Sơn said

    Thầy cho em hỏi 1 câu: Trong access em có lưu đường link dến file excel.bây giờ em muốn dùng c#(viết ứng dụng đa tầng) để load đường dẫn file excel ra,để khi người dùng click vào đó thì file excel sẽ mở ra.

    Nhờ thầy cùng các bạn giúp mình
    Thanks

  30. vungoimora said

    Đây là folder tree view của mình, các bạn tham khảo nhé http://www.megaupload.com/?d=P7MUOMS4

  31. hoadienanh said

    thầy có thể hướng dẫn e cách load data từ sql ra GridEX trong Janus được ko ạ. Em cảm ơn thầy nhiều!

  32. vovanhai said

    Thầy không dùng các components của hãng thứ 3.

  33. AnhTuan said

    chào thầy , em đã sử dụng đoạn code trên để xây dựng chương trình của mình ,nhấn 1 nút trên form chính hiện lên form trình chiếu ảnh em gặp 2 vấn đề sau :
    thứ nhất: nếu thư mục quá nhiều ảnh thì chương trình nạp lên heap sẽ báo thiếu bộ nhớ ( cái này không fix cũng đc chỉ cần hạn chế vừa đủ số hình là ok )
    vấn đề thứ 2 là khi em đóng form trình chiếu ảnh , nhưng sao Task manager không giải phóng vùng nhớ đã cấp cho cho form này , em liên tục mở form trình chiếu ảnh bằng nút trên form chính đến 1 lúc nào đó thì bộ nhớ bị đầy và báo lỗi😦 ko cho mở form chình chiếu ảnh nữa , mặc dù em chỉ mở 1 form trong 1 thời điểm😦 chỉ khi em thoát form chính và chạy lại thì nó mới giai phóng😦
    mong thầy giúp đõ em , em xin cảm ơn

  34. Đường dẫn trong Resource said

    Em chào thầy,

    Thưa thầy cho em hỏi vấn đề về đường dẫn file trong Resource với ạ

    Em muốn thay ảnh của pictureBox bằng 1 ảnh trong Resource
    Nhưng đường dẫn ảnh thì em ko biết lấy sao cả, Mong thầy chỉ dùm em với

      string chuoi=@"D:\Documents and Settings\BadBoy\My Documents\Visual Studio 2008\Projects\Break_Mouse\Break_Mouse\Resources\9.gif";
    
    //Thay ảnh vào picture
    pictureBox.Image=chuoi;
    
    

    …——> Sử dụng đường dẫn trên thì sang máy khác chắc sẽ mất hình
    Mong thầy cho em hướng giải quyết để ứng dụng làm xong có thể hoàn thiện nhất ạ.
    Em xin cảm ơn thầy,
    Chúc thầy và gia đình luôn mạnh khỏe

  35. vovanhai said

    Dùng Image.FromFile(path);

  36. hoadienanh said

    Thầy ơi, nếu e muốn lựa chọn nhiều ảnh từ openDialog rồi đưa tất cả các lựa chọn ảnh đó vào textbox thì như thế nào ạ (e mới chỉ lấy được 1 ảnh từ openDialog và hiển thị ra textbox thôi). Em cảm ơn!

    openDialog.Filter = “JPeg Image|*.jpg|Bitmap Image|*.bmp|Gif Image|*.gif|Images(*.jpg,*.bmp,*.gif)|*.jpg;*.bmp;*.gif|All Files|*.*”;

    openDialog.AddExtension = true;
    openDialog.Multiselect = false;
    //openDialog.Multiselect = true; (true nếu muốn chọn nhiều ảnh)

    if (openDialog.ShowDialog() == DialogResult.OK)
    {
    String filePath = openDialog.FileName;
    //String []filePath = openDialog.FileNames;
    this.pbDispatchGo.ImageLocation = openDialog.FileName;
    //Lấy đường dẫn ảnh ra textbox
    this.txtBrowDispG.Text = filePath.ToString();
    }

  37. hoadienanh said

    Em làm được rồi.hì. ^^

  38. vovanhai said

    String []filePath = openDialog.FileNames;
    for(String fn in filePath){
    this.txtBrowDispG.Text+=fn+”;”;
    }

  39. Giang said

    chào thầy, em có thể xin địa chỉ email hoặc nick yahoo của thầy ko? em cũng đang làm thực tập chuyên ngành về vẫn đề này nên rất muốn được thầy giúp đỡ. Em xin cảm ơn !

  40. Võ Văn Hải said

    mail của tôi ở mục about

  41. NSH said

    lam the nao de load 1 buc anh len picture box bang bit map duoc ah.e rat la ga vi e chua biet jii ve c#.

  42. xxxxx said

    sao khong share code luon cho nhanh.tui down khong duoc!

  43. Tea said

    Chào thầy,

    Em có vần đề này xin thầy chỉ giúp.Em đang làm một ứng dụng nhỏ dùng để đối xứng một image trong pictureBox theo truc Y hoặc X.Nhưng em không làm đượcmông thầy giúp cho.

    (ứng dụng gồm: một picturebox, 2 button(btnDoixungX: làm cho ảnh đối xứng qua trục X; btnDoixungY: làm co ảnh đối xứng qua trục Y))

    Cám ơn thầy trước.

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.Runtime.InteropServices;

    namespace doixung
    {
    public partial class Form1 : Form
    {
    public Form1()
    {
    InitializeComponent();
    }

    IntPtr pTarget, pOrig;
    Bitmap bmp;

    [DllImport("gdi32.dll")]
    static extern bool StretchBlt(IntPtr hdcDest, int nXOriginDest,
    int nYOriginDest, int nWidthDest, int nHeightDest, IntPtr hdcSrc,
    int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc,
    TernaryRasterOperations dwRop);

    [DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)]
    static extern IntPtr CreateCompatibleDC(IntPtr hdc);

    [DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)]
    static extern bool DeleteDC(IntPtr hdc);

    [DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)]
    static extern IntPtr SelectObject(IntPtr hdc, IntPtr hgdiobj);

    public enum TernaryRasterOperations
    {
    SRCCOPY = 0x00CC0020, /* dest = source*/
    };

    private void btnSymmetricalX_Click(object sender, EventArgs e)
    {
    // code không chạy được.
    IntPtr hbmp;
    bmp = new Bitmap(doixung.Properties.Resources.bg4);
    hbmp = bmp.GetHbitmap();
    IntPtr pSource1 = CreateCompatibleDC(pTarget);
    pOrig = SelectObject(pSource1, hbmp);
    StretchBlt(pTarget, 0, bmp.Height, bmp.Width, bmp.Height * -1, pSource1, 0, 0, bmp.Width, bmp.Height, TernaryRasterOperations.SRCCOPY);
    DeleteDC(pSource1);
    }

    private void PictureBox1_Paint(object sender, PaintEventArgs e)
    {
    pTarget = e.Graphics.GetHdc();

    ////đối xứng được nhưng hình cũ vẫn còn và độ dài,rộng không thích hợp
    //IntPtr hbmp;
    //bmp = new Bitmap(doixung.Properties.Resources.bg4);
    //hbmp = bmp.GetHbitmap();
    //IntPtr pSource = CreateCompatibleDC(pTarget);
    //pOrig = SelectObject(pSource, hbmp);
    //StretchBlt(pTarget, 0, PictureBox1.Height, PictureBox1.Width, PictureBox1.Height * -1, pSource, 0, 0, PictureBox1.Width, PictureBox1.Height, TernaryRasterOperations.SRCCOPY);
    //DeleteDC(pSource);

    e.Graphics.ReleaseHdc(pTarget);
    }
    }
    }

  44. Võ Văn Hải said

    Viết giống kiểu VB6 quá vậy bạn. Bạn thử dùng Brush xem sao. Ví dụ:

     private void pictureBox1_Paint(object sender, PaintEventArgs e)
            {
                TextureBrush tex = new TextureBrush(pictureBox1.Image,WrapMode.TileFlipXY);
              
                e.Graphics.FillRectangle(tex,e.ClipRectangle);
                tex.Dispose();
            }
    

    Hoặc dùng phương thức RotateFlip để quay theo các góc được chỉ định như ví dụ sau:

     Image image = Image.FromFile("tulip.jpg"); 
     pictureBox1.Image = image;
    
     Image img = (Image)image.Clone();
     img.RotateFlip(RotateFlipType.Rotate90FlipXY);
     pictureBox2.Image = img;
    
  45. findme said

    Chào thầy
    Em muốn hỏi thầy là hàm foreach dùng dể làm gì?

  46. Võ Văn Hải said

    EM tìm hiểu kỹ C# đã nhé! Đây là phát biểu lặp trong tập hợp.

  47. vuonhoatientu said

    Thưa thầy, em tạo một cơ sở dữ liệu, trường hinhanh được lưu theo kiểu binary, giờ em muốn load hình ảnh vào datalist thì phải làm như thế nào, mong thầy giúp đỡ

  48. Võ Văn Hải said

    Em dùng code:

      Byte[] i = (byte[])row.Cells[5].Value;
      MemoryStream stmBLOBData = new MemoryStream(i);
      picHinh.Image = Image.FromStream(stmBLOBData);
    

    trong do row là 1 datarow chứa mẫu tin có hình ảnh ở cột số 5
    picHinh là PictureBox để hiển thị

  49. Thanh Nam said

    Thầy ơi e viết ctrinh như vậy nhưng ko biết sai cái j? E chạy ko đc.Mog thầy sửa cho e
    //Viet ctrinh giai pt bac 2
    //Khai bao bien
    double a, b, c, x1, denta,x2;
    //Nhap a,b,c
    Console.WriteLine(“Nhap he so a:”);
    a = double.Parse(Console.ReadLine());
    if (a==0)
    {
    Console.WriteLine(“DK cua pt la heso a:Phai khac 0”);
    Console.ReadLine();
    }
    Console.WriteLine(“Nhap he so b:”);
    b = double.Parse(Console.ReadLine());
    Console.WriteLine(“Nhap he so c:”);
    c = double.Parse(Console.ReadLine());
    //Tinh denta
    denta = (b * b – 4 * (a * c));
    denta = double.Parse(Console.ReadLine())
    if (denta0)
    {
    x1 = Convert.ToSingle((Math.Sqrt(denta) – b) / (2 * a));
    x2 = Convert.ToSingle((-Math.Sqrt(denta) – b) / (2 * a));
    }
    else
    {
    Console.WriteLine(“Phuong trinh co nghiem kep”);
    x1 = x2 = (-b / 2 * a);
    Console.ReadLine();
    }
    Console.ReadLine();

  50. hieu said

    Thưa thầy cho em hỏi: làm cách nào để tìm từ gần đúng trong winform.
    Vd: khi em viết vào textbox một kí tự bất kì thì nó sẽ hiện ra một danh sách các tìm gần đúng

  51. Võ Văn Hải said

    “làm cách nào để tìm từ gần đúng trong winform?”
    Bạn có thể chọn thuộc tính AutoCompleteCustomeSource/AutoCompleteSource và AutoCompleteMode của textBox control.

  52. chào thầy,

    ko biết cái này mình code get thư muc trên server hay host dc ko thầy

  53. hoàng phúc said

    thưa thầy ngoài những gì đã trình bài mình còn có thể lấy tọa độ,tên đuôi ảnh,phân tích ảnh không thầy?

  54. phương ngọc said

    Thưa thầy, thầy có biết chương trình viết về mạng nơron bằng c# không a.? Em làm về phân cụm dữ liệu sử dụng giải thuật Fuzzy Bi-directional Associative Clustering Network mà không biết viết thế nào?

  55. Nga said

    thumbnailsFLP.Controls.Clear();

    displayPictureBox.Image = null;

    Thầy cho em hỏi là thumbnailsFLP và displayPictureBox khai bảo biến của nó ở đau vậy thầy? Bài em làm bị báo lỗi ở 2 dòng này ạh

  56. Võ Văn Hải said

    Đây là tên của 2 controls trên form.

  57. ThuHuong said

    Xin chào mọi người !!mình đang làm 1 ứng dụng xem hình như trên nhưn muốn phát triển thêm cái next hình như ko biết làm thế nào?Mọi người giúp mình với ah!

  58. luong said

    e đang viết chương trình đọc vào 1 ảnh và đưa các điểm ảnh RGB ra file excel mà chưa biết làm sao ? help me!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: