TakePicture - Using the internal camera from your application
I wanted to be able to take pictures using the internal camera of an Asus P750 right from my application.
I've first tried the "native" approach and downloaded the code of Wimo (worth a look).
However the pictures taken were distorted and the whole process was unstable (crashing from time to time).
My second attempt was to call the CameraCaptureDialog which has a "managed" api. Dzt has already created a wrapper for it: http://www.basic4ppc.com/forum/addit....html#post6033
I wanted to show the camera dialog and then send a keypress message that will take the picture and then somehow close the dialog.
However this didn't work as well, throwing InvalidOperationException every time.
After searching a little bit it is clear that it is a common problem and this api is not supported by all devices.
The third attempt seems to work.
Instead of calling the CameraCaptureDialog we are launching camera.exe.
The drawback is that we can't change the default settings like resolution and file name.
Using a timer we are waiting 5 seconds before sending the "Ok" key message which takes a picture and then after another 5 seconds we close the process with Process.CloseMainWindow.
This program requires agraham's threading library (only for the Process object).
The source code is attached.
Code:
Sub Globals tick = 0 End Sub
Sub App_Start Form1.Show process.New1 hardware.New1 timer1.Interval = 5000 End Sub
Sub btnTakePicture_Click timer1.Enabled = True process.Start("\windows\camera.exe","") End Sub
Sub AfterPicture file = FindLastFile("\my documents\my pictures\","pic") label1.Text = FileName(file) image1.Image = file End Sub Sub FindLastFile (path, prefix) ArrayList1.Clear FileSearch(ArrayList1,path,prefix & "*.jpg") 'We assume that the last taken image name will be the last name in the sorted list. 'This assumption might be wrong. ArrayList1.Sort(cCaseSensitive) Return ArrayList1.Item(ArrayList1.Count-1) End Sub
Sub Timer1_Tick tick = tick + 1 If tick = 1Then'take picture hardware.KeyPress(13) Else timer1.Enabled = False process.CloseMainWindow tick = 0 AfterPicture EndIf End Sub
I wanted to be able to take pictures using the internal camera of an Asus P750 right from my application.
At the first download, it worked on the Desktop-PC, but not on the Pocket-PC, because the "Hardware.DLL" was not installed automatically.
Then I copied the "Hardware.DLL" onto the Pocket-PC.
1) The application started.
2) When clicking the Button "TakePicture", the internal camera started.
3) It seems, that the camera made a photo by itself (without pressing any key).
4) Then came this Error-Message:
__________________
JOTHA | Greetz from the Schwabenländle.
Pocket-PC: HTC HD2 (Dual-Boot WindowsMobile 6.51 + Android 2.2 Froyo)
On my Pocket-PC I don´t have a choice by my own to set the path. I have an AMEO (= HTC ADVANTAGE X 7500) and there are 3 possible choices.
1) Gerät [= Device] The path is: ("\My Documents\Eigene Bilder\",jpg")
2) Speicherkarte [= Mini SD-Card] The path is: ("\Speicherkarte\DCIM\100MEDIA\",jpg")
3) MicroDrive [= built in 8 GB Drive] I didn´t try it yet.
--> Certainly I had a look at the right path (where the taken pictures were sent to).
The error-message was:
Quote:
An error occurred on sub main.findlastfile.
Line number: 40
Return
ArrayList1.Item(ArrayList1.Count-1)
Error description:
Es kann keine Fehlermeldung angezeigt werden, da die optionale Ressource der Assembly, die die Fehlermeldung enthält, nicht gefunden wurde.
Continue?
Thank you in Advantage!
__________________
JOTHA | Greetz from the Schwabenländle.
Pocket-PC: HTC HD2 (Dual-Boot WindowsMobile 6.51 + Android 2.2 Froyo)
You should set line 18 to the same folder that your camera stores images by default.
Open this folder and see what are the names of the pictures files.
On my device the names are:
PIC001.jpg
PIC002.jpg
...
This modified version of Erel's code works on my XDA.
'Modify the pictures location to suit your device.'
All it does is check the directory, and loads the newest picture,
(the one that's just been took).
Green bit below is optional.
Code:
Sub Globals tick = 0 End Sub
Sub App_Start Form1.Show process.New1 hardware.New1 timer1.Interval = 5000 End Sub
Sub Button1_Click timer1.Enabled = True process.Start("\windows\camera.exe","") End Sub
Sub AfterPicture ArrayList1.Clear FileSearch(ArrayList1,"<font color="Blue">\Storage Card\My Documents\My Pictures\</font>","*.jpg") file=ArrayList1.Item(arraylist1.Count-1) <font color="lime">label1.Text = file'full path and file name 'label1.Text = FileName(file) 'just file name</font> image1.Image = file End Sub
Sub Timer1_Tick tick = tick + 1 If tick = 1Then'take picture hardware.KeyPress(13) Else timer1.Enabled = False process.CloseMainWindow tick = 0 AfterPicture EndIf End Sub
__________________
.
.
. Don't ask, I'm fine, honest. !!
.
.
. Just a little crazy at times
O2 XDA, GW Evo 2.1 UC WWE Rom, WM6.1
Radio Ver 03.34.90
With Basic4ppc V6.80
I made a little workaround with yours an Erels code.
- Now you can change the location where the pictures are stored. (green)
- Now you can press the hardbutton to take a photo by yourself.
- It is made as a module, so you can implement it better to your apps.
- ... and some other little changes ...
The shell is in german, if someone needs it in english, please post here.
I hope it is helpful for someone.
Have fun!
Code:
'------------------------------------------------------ 'Modul BildAufnahme 'Build 0066 '------------------------------------------------------ 'ben�tigt Hardware.dll 'ben�tigt HardwareDesktop.dll 'ben�tigt Threading.dll 'ben�tigt Objekt "hardware" aus Hardware 'ben�tigt Objekt "process" aus Process '------------------------------------------------------ Sub Globals tick = 0 End Sub '------------------------------------------------------ Sub BildAufnahme_Show process.New1 hardware.New1 Timer1.Interval = 5000 End Sub '------------------------------------------------------ Sub Button1_Click PanelEinstellungen.Visible = False If cPPC Then i = Msgbox ("Wollen Sie jetzt die Kamera starten?", " Hinweis", cMsgboxYesNo, cMsgboxQuestion) If i = cYes Then Panel1.Visible = True Button1.Visible = False Button3.Visible = True EndIf Else Msgbox ("Bilder aufnehmen funktioniert nur auf dem Pocket-PC mit eingebauter Kamera.", "Hinweis", cMsgboxOK, cMsgboxExclamation) EndIf End Sub '------------------------------------------------------ Sub AfterPicture ArrayList1.Clear FileSearch(ArrayList1,<font color="Lime">""&Speicherort.Text&"","*.jpg")</font> file = ArrayList1.Item (ArrayList1.Count-1) Label1.Text = file Image1.Image = file WaitCursor (False) End Sub '------------------------------------------------------ Sub Button2_Click WaitCursor (True) ' Panel3.Visible = True AfterPicture Button2.Visible = False Label7.Visible = True End Sub '------------------------------------------------------ Sub Button3_Click 'Button "Weiter" nach der Anleitung WaitCursor (True) Timer1.Enabled = True Timer1_Tick Shell ("Camera.exe", "") Panel1.Visible = False Button1.Visible = False Button2.Visible = True WaitCursor (False) End Sub '------------------------------------------------------ Sub Timer1_Tick tick = tick + 1 If tick = 1Then'Panel2 "Kamera wird gestartet" zeigen Panel2.Visible = True Else Timer1.Enabled = False Panel2.Visible = False tick = 0 EndIf End Sub '------------------------------------------------------ 'Einstellungen des Speicherorts f�r Bilder '------------------------------------------------------ Sub ButtonEinstellungen_Click ButtonEinstellungen.Visible = False PanelEinstellungen.Visible = True End Sub
Sub ButtonEinstellungenSchliessen_Click ButtonEinstellungen.Visible = True PanelEinstellungen.Visible = False End Sub '------------------------------------------------------ 'Bild im Verzeichnis l�schen '------------------------------------------------------ Sub ButtonLoeschen_Click ArrayList1.Clear End Sub
__________________
JOTHA | Greetz from the Schwabenländle.
Pocket-PC: HTC HD2 (Dual-Boot WindowsMobile 6.51 + Android 2.2 Froyo)
after I changed some details and put it into my app, there was an error message.
So I thought it was my fault.
Then I tried your original-code again, but with one change: the place where the photo is stored (see blue colored):
Code:
<font color="YellowGreen">'Original von Erel - Build 0002</font> Sub Globals tick = 0 End Sub
Sub App_Start Form1.Show process.New1 hardware.New1 timer1.Interval = 5000 End Sub
Sub Button1_Click timer1.Enabled = True process.Start("\windows\camera.exe","") End Sub
Sub AfterPicture file = FindLastFile<font color="Blue">("\Speicherkarte\DCIM\100MEDIA\","imag")</font> label1.Text = FileName(file) image1.Image = file End Sub Sub FindLastFile (path, prefix) ArrayList1.Clear FileSearch(ArrayList1,path,prefix & "*.jpg") 'We assume that the last taken image name will be the last name in the sorted list. 'This assumption might be wrong. ArrayList1.Sort(cCaseSensitive) Return ArrayList1.Item(ArrayList1.Count-1) End Sub
Sub Timer1_Tick tick = tick + 1 If tick = 1Then'take picture hardware.KeyPress(13) Else timer1.Enabled = False process.CloseMainWindow tick = 0 AfterPicture EndIf End Sub
I didn´t change anything else, but this error message was shown:
What resolution does your camera use?
When you load an image file the image file is converted to a raw bitmap. So even if the jpg file is not large, the memory it takes can be too large.
You can use a Bitmap object from the ImageLib library to store the image and before loading a new image dispose the old one:
Code:
Sub App_Start Bitmap1.New2(1,1) 'Create a dummy image. End Sub