全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:4165
推到 Plurk!
推到 Facebook!

如何讀取SD讀卡機中SD卡的影像資料

答題得分者是:derrenbol1
sunwingman
一般會員


發表:26
回覆:47
積分:14
註冊:2008-05-14

發送簡訊給我
#1 引用回覆 回覆 發表時間:2009-09-20 23:50:28 IP:221.169.xxx.xxx 訂閱

想請教各位前輩~
我要怎麼才能讀取SD讀卡機中SD卡的影像資料?

現在我有一個案子,有一台SD讀卡機
然後插入SD卡之後,程式要能自動抓取SD卡中的影像,秀在Image元件中

目前卡在我不知道要怎麼去偵測SD卡插入,然後讀取裡面的資料
不知道有沒有前輩有作過類似的專案?
boss.tw
高階會員


發表:15
回覆:109
積分:194
註冊:2005-05-17

發送簡訊給我
#2 引用回覆 回覆 發表時間:2009-09-21 17:03:18 IP:219.87.xxx.xxx 訂閱
sunwingman
一般會員


發表:26
回覆:47
積分:14
註冊:2008-05-14

發送簡訊給我
#3 引用回覆 回覆 發表時間:2009-09-23 10:56:49 IP:61.61.xxx.xxx 訂閱
感謝boss.tw的回覆
我先試一下,有問題我再提出來,感謝!

sunwingman
一般會員


發表:26
回覆:47
積分:14
註冊:2008-05-14

發送簡訊給我
#4 引用回覆 回覆 發表時間:2009-09-23 20:39:34 IP:61.61.xxx.xxx 訂閱
想請問boss.tw,
用Device Management Events,除了可以偵測裝置的插拔外,
有辦法拿來讀取SD卡裡面的資料嗎?

因為我看範例中,他是用Device Management Events來偵測裝置的插拔
可是我查了一下MSDN,發現他好像沒有可以用來讀取資料的函式耶??
因為這方面的程式我還不熟,所以如果有誤會的話請前輩們指正!


===================引 用 boss.tw 文 章===================
DEVICECHANGE
請參考 http://delphi.ktop.com.tw/board.php?cid=31&fid=79&tid=91493
sunwingman
一般會員


發表:26
回覆:47
積分:14
註冊:2008-05-14

發送簡訊給我
#5 引用回覆 回覆 發表時間:2009-09-24 20:58:47 IP:61.61.xxx.xxx 訂閱

[code cpp]
#include
#pragma hdrstop

#include "Unit1.h"
#include //needed
#include //needed
#include
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;

DEFINE_GUID(USBIODS_GUID,0xa5dcbf10,0x6530,0x11d2,0x90,0x1f,0x00,0xc0,0x4f,0xb9,0x51,0xed);
char* Devices[10];

//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button1Click(TObject *Sender)
{
int DeviceNum;
DeviceNum = FindDeviceName();

}
//---------------------------------------------------------------------------

int __fastcall TForm1::FindDeviceName()
{
//TODO: Add your source code here
HDEVINFO hinfo = SetupDiGetClassDevs(&USBIODS_GUID, NULL, NULL,
DIGCF_PRESENT|DIGCF_INTERFACEDEVICE); //取得目前HID裝置的資訊

int i;
for(int i=0;; i)
{
SP_DEVICE_INTERFACE_DATA Interface_Info; //宣告界面的資料
Interface_Info.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); //宣告界面資料的大小, 要設成一個Byte Alignment

if(!SetupDiEnumDeviceInterfaces(hinfo, NULL, (LPGUID)&USBIODS_GUID, i, &Interface_Info)) //列舉裝置
{
SetupDiDestroyDeviceInfoList(hinfo);
return i;
}

DWORD needed;
//第一次調用InterfaceDetail , 得到needed大小
SetupDiGetDeviceInterfaceDetail(hinfo, &Interface_Info, NULL, 0, &needed, NULL);
PSP_INTERFACE_DEVICE_DETAIL_DATA detail = (PSP_INTERFACE_DEVICE_DETAIL_DATA)malloc(needed);

if(!detail)
{
SetupDiDestroyDeviceInfoList(hinfo);
return i;
}

detail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
if(!SetupDiGetInterfaceDeviceDetail(hinfo, &Interface_Info, detail, needed, NULL, NULL))
{
free((PVOID)detail);
SetupDiDestroyDeviceInfoList(hinfo);
return i;
}

char name[MAX_PATH];
strncpy(name, detail->DevicePath, sizeof(name)); //從detail->DevicePath複製到name
free((PVOID)detail);
Devices[i] = name;
}

}

[/code]

我已經可以用上面的程式碼找到DeviceName,現在我要讀取記憶卡裡面的資料
所以要接下來就是要CreateFile來得到Device的Handle
但是接下來,我可以直接用ReadFile來讀取裡面的資料嗎?還是一定要透過DeviceIoControl?

再次請教各位前輩們,拜託了,感謝!!!



sunwingman
一般會員


發表:26
回覆:47
積分:14
註冊:2008-05-14

發送簡訊給我
#6 引用回覆 回覆 發表時間:2009-09-25 14:43:59 IP:61.61.xxx.xxx 訂閱
各位前輩好,
現在我可能要改成使用多合一的讀卡機,
我現在有一個想法是,

我是不是可以去取得當多合一讀卡機插入之後
會多出來的磁碟機代號,ex:M、N、O、P
然後在進入磁碟機目錄裡面,找尋圖檔副檔名,ex:.jpg or .bmp
然後把他秀在Image元件裡呢?

因為我現在卡在我不知道要怎麼用DeviceIoControl去讀取圖檔
所以提出上面方法,
不知道是否可行?
拜託前輩們指導一下....
derrenbol1
中階會員


發表:5
回覆:113
積分:93
註冊:2004-12-09

發送簡訊給我
#7 引用回覆 回覆 發表時間:2009-09-25 15:58:24 IP:219.87.xxx.xxx 訂閱
Sunwingman :

不懂為何你得要用DeviceIoControl去操作裝置 . 既然磁碟機都知道了
那用一般的File I/O去做搜尋及開啟不就好了.


請參考.
sunwingman
一般會員


發表:26
回覆:47
積分:14
註冊:2008-05-14

發送簡訊給我
#8 引用回覆 回覆 發表時間:2009-09-25 20:41:43 IP:59.105.xxx.xxx 訂閱

謝謝derrenbol1回覆,

所以derrenbol1的意思是說,
如果我用GetTypeDrive取得我多合一讀卡機磁碟機代號後,
例如:M、N、O、P四個REMOVEABLE Type的Driver,
那麼我就可以直接用File I/O分別對四個Driver作讀取的動作嗎?

那我先試試看!感謝derrenbol1~

編輯記錄
sunwingman 重新編輯於 2009-09-25 20:45:02, 註解 無‧
sunwingman
一般會員


發表:26
回覆:47
積分:14
註冊:2008-05-14

發送簡訊給我
#9 引用回覆 回覆 發表時間:2009-09-27 03:41:41 IP:59.105.xxx.xxx 訂閱

我現在可以用下面程式碼去得到讀卡機裡面的影像了,
感謝boss.tw及derrenbol1的回覆及幫忙!!
不過我現在有另外一個問題,
就是因為是多合一讀卡機,
當我找出REMOVEABLE Type的磁碟機代號,
然後去訪問,假如說那個插槽沒有插卡
那麼就會顯示錯誤,所以我只能去拜訪有插卡的磁碟機
請問要有什麼方法可以只拜訪有插卡的磁碟機呢?

我有另開一個主題:
http://delphi.ktop.com.tw/board.php?cid=168&fid=917&tid=99465
請前輩們在多多指教!


[code cpp]
#include //for chdir()
#include
#include

void __fastcall TForm1::DirFiles(AnsiString RootDir, bool chkSubDir, bool incPath)
{
//TODO: Add your source code here
chdir(RootDir.c_str()); // 切換到指定目錄去
TSearchRec Sr; // 設Sr為存放檔案資訊的結構變數
AnsiString FileName; // 設定檔案名稱之用的暫存變數

int done = FindFirst("*.*", faDirectory | faAnyFile, Sr);
while (done == 0)
{
if (!(Sr.Attr & faDirectory)) // 如果是檔案
{
if (incPath) // 如果檔名要包含路徑資料在內
{
char curdir[MAXPATH 1];
GetCurrentDirectory(MAXPATH, curdir); // 取得現行目錄名稱
FileName = AnsiString(curdir) "\\" Sr.Name; // 設定含路徑的檔名
}
else
FileName = Sr.Name; // 設定不含路徑的檔名

Memo1->Lines->Add(FileName); // 此處設置您自己要處理的動作
}
else if(chkSubDir) // 如果要檢查次目錄內的檔案
{
if (Sr.Name != "." && Sr.Name != "..") // 如果不是相對目錄代碼的話
{
DirFiles(Sr.Name.c_str(), true, incPath); // 如果是目錄的話就遞迴處理
chdir(String("..").c_str()); // 切換回前一層目錄
}
}
done = FindNext(Sr); // 找目錄中的下一個檔案
}

FindClose(Sr);
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button1Click(TObject *Sender)
{
LPTSTR lpBuffer;
DWORD dwDeviceCnt;
DWORD SecPerCls,BytesPerSec,NumOfFreeCls,TotalNumOfCls;
double DiskSpace;
dwDeviceCnt = GetLogicalDriveStrings(0, lpBuffer); //讀到字串的大小

if(dwDeviceCnt)
{
char *buf = new char[dwDeviceCnt];
GetLogicalDriveStrings(dwDeviceCnt, buf);
for(DWORD idx=0; idx<(dwDeviceCnt-1); idx)
{
if(buf[idx]==0)
buf[idx] =' ';
}

AnsiString sDevice=buf;
while(!sDevice.IsEmpty())
{
sDevice.Delete(1,sDevice.Pos(" "));
vStrDevice.push_back(sDevice.SubString(1,sDevice.Pos(" ")-1));
}


AnsiString Dir;
for(int idx=0; idx {
switch(GetDriveType(vStrDevice[idx].c_str()))
{
case DRIVE_REMOVABLE:
Dir = vStrDevice[idx]; //這個就是可移除的裝置,例如:usb的磁碟機,軟碟機等
bool CheckSubDirectory = true; // 取得檔案名稱時是否要檢查次目錄內的檔案?
bool NameIncludePath = true; // 取得檔案名稱時是否要包含路徑名稱?
DirFiles(Dir, CheckSubDirectory, NameIncludePath);
break;
}
}

delete buf;
}

}
//---------------------------------------------------------------------------

[/code]


GGL
資深會員


發表:104
回覆:600
積分:335
註冊:2006-11-05

發送簡訊給我
#10 引用回覆 回覆 發表時間:2009-11-04 14:41:26 IP:61.57.xxx.xxx 訂閱
用SCSI COMMAND 0X00,確定有插卡再動作
Coffee
版主


發表:31
回覆:878
積分:561
註冊:2006-11-15

發送簡訊給我
#11 引用回覆 回覆 發表時間:2009-11-04 15:40:59 IP:59.124.xxx.xxx 訂閱
我用比較取巧的方法,GetLastError();...:P

===================引 用 GGL 文 章===================
用SCSI COMMAND 0X00,確定有插卡再動作
------
不論是否我發的文,在能力範圍皆很樂意為大家回答問題。
為了補我的能力不足之處,以及讓答案可以被重複的使用,希望大家能儘量以公開的方式問問題。
在引述到我的文時自然會儘量替各位想辦法,謝謝大家!
系統時間:2017-10-23 21:28:08
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!