Hi,
i’m trying to get my head around how i can convert a picture taken with the camera (as explained here) into a Base64 String to save or send to my server.
Best regards
Till
Hi,
i’m trying to get my head around how i can convert a picture taken with the camera (as explained here) into a Base64 String to save or send to my server.
Best regards
Till
Hey Till, thanks for posting in the forum. We are working on getting both the Camera and IO api a bit better, but this should work:
var Camera = require('FuseJS/Camera');
Camera.takePicture({targetWidth:20, targetHeight:20}).then(function(file){
var reader = new FileReader();
reader.onloadend = function() {
console.log(reader.result);
};
reader.readAsDataURL(file);
}).catch(function(e){
console.log(e);
});
Oh, you mean capture the effect in UX. I think you have to go into Uno land to do that. I will see if I get time to create an example for you.
Hey Anders,
your first solution was exactly what i was looking for. Thanks a lot
Hey Anders,
i’m running into an issue now. This method works the first time i use it, but when taking another picture, the call to reader.readAsDataURL
fails.
While debugging i found out, that the resulting file of Camera.takePicture
is the same as before (e.g. /var/mobile/Containers/Data/Application/94E711F4-80FC-460B-8A7F-51226C275A5E/Documents/temp.jpg). This might be an issue, as the file already exists.
Here is my code, can you take another look at this?
<App Theme="Basic">
<Panel>
<JavaScript>
var Observable = require('FuseJS/Observable');
var Camera = require('FuseJS/Camera');
var imageString = Observable("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAADaSURBVDhPtZK9CYRAFISvNhEUURDEwAIMLMAWLMHcxMDQMqzAxCIUxUSdY/f2+cfbC05u4Iuc+VjWfeFh/itYluUrIlpBURQwTVOL7/sYx5EX9H0Pz/NgWZaWqqpklxVkWcaOiDiOVZMRtG0L27bZIdE0jWrfBOu6IkkSdkSkaSp7lIugrmt2RARBgGEYVPuTXSA+uK7LDomyLFX7yC7I85wdEWEYYp5n1T4iBV3XwXEcdkicL+6cl3hRURTBMAwt4uLo5d0jTyCONk2Tlm3bZJnL5S/8kocC4A2RfkKIvwD9JQAAAABJRU5ErkJggg==");
console.log("##########################################");
function takePicture()
{
Camera.takePicture({targetWidth:128})
.then(function(file)
{
console.log( "picture taken: " + file.path );
convertPictureToBase64( file );
})
.catch(function(e)
{
console.log( "error: " + e );
});
}
function convertPictureToBase64( file )
{
console.log("converting to Base64.");
var reader = new FileReader();
reader.onloadend = function()
{
//console.log( reader.result ); console.log( "conversion finished" );
console.log("**"); imageString.value = reader.result;
};
reader.readAsDataURL( file );
}
module.exports =
{
imageString : imageString,
takePicture : takePicture,
};
</JavaScript>
<StackPanel Orientation="Vertical">
<Image Width="64" Height="64" ux:Name="picture1" >
<Base64ImageSource Base64="{imageString}" />
</Image>
<Button Height="48" Text="Take picture" Clicked="{takePicture}" />
</StackPanel>
</Panel>
</App>
</code></pre></div>
<p>EDIT: Saving the file with the same name into the same folder is most likely no the cause of the problem. I was sometimes able to take 3 pictures without problems, then breaking it on the fourth picture.</p>
<p>This is my StackTrace from XCode (no errors in Fuse Monitor)</p>
<div class="highlighted_code"><pre><code class="language-uno">* thread #22: tid = 0x5ab8, 0x0000000100348568 base64Testg::Fuse::Scripting::FactoryClosure::Run() [inlined] uType::T(this=0x7000000000000000, index=0) at ObjectModel.h:848, stop reason = EXC_BAD_ACCESS (code=1, address=0x7000000000000078)
* frame #0: 0x0000000100348568 base64Testg::Fuse::Scripting::FactoryClosure::Run() [inlined] uType::T(this=0x7000000000000000, index=0) at ObjectModel.h:848 [opt]
frame #1: 0x0000000100348568 base64Testg::Fuse::Scripting::FactoryClosure::Run(this=0x0000000152e31110) + 48 at Fuse.Scripting.g.cpp:1010 [opt]
frame #2: 0x00000001004f690c base64Testinvoke_delegate(arg=<unavailable>) + 44 at posix_thread.h:15 [opt]
frame #3: 0x0000000181753b28 libsystem_pthread.dylib_pthread_body + 156
frame #4: 0x0000000181753a8c libsystem_pthread.dylib`_pthread_start + 156
Hi Anders, I’m also having issues, specifically with FileReader
.
I followed your example, copy-paste in fact, and every time I attempt to run the code my app crashes (running on Android 4.4.2 Galaxy S4).
If I comment out the line reader.readAsDataURL(file);
my app will run, but of course I’m not able to do what I’m trying to do.
I also tried using Storage.read(file.path)
, this will successfully get into my promise callback but the contents of the file are read as blank, example:
var Observable = require('FuseJS/Observable');
var Camera = require('FuseJS/Camera');
var Storage = require('FuseJS/Storage');
var picture = Observable();
function takePicture(){
Camera.takePicture({targetWidth:1000, targetHeight:1200}).then(function(file){
Storage.read(file.path).then(function(file_content){
console.log(file.name);
console.log(file_content);
var obj = {'file' : file_content};
fetch('http://testurl', {
method: 'POST',
body: JSON.stringify(obj)
}).then(function(response) {
console.log(response.status)
console.log(response.text())
}).catch(function(err) {
console.log(err.message);
});
}).catch(function(err){
console.log(err.message);
});
}).catch(function(e){
console.log(e);
});
}
file.path
will return something like "/storage/emulated/0/Android/data/com.photoapp/files/JPEG_12_-452507721.jpg"
and my response.status
properly returns 200
. However, file_content
is returning an empty string.
Ideally I would use the base64 method you outlined earlier, but like I said, the line reader.readAsDataURL(file);
causes my app to crash.
Any advice is greatly appreciated.
I have the same problem My app crash!
Anders Bondehagen wrote:
Hey Till, thanks for posting in the forum. We are working on getting both the Camera and IO api a bit better, but this should work:
var Camera = require('FuseJS/Camera'); Camera.takePicture({targetWidth:20, targetHeight:20}).then(function(file){ var reader = new FileReader(); reader.onloadend = function() { console.log(reader.result); }; reader.readAsDataURL(file); }).catch(function(e){ console.log(e); });
When I use preview on my Android device like this:
Work fine! But when I export my app to apk via terminal (uno build --target=Android -run) the app Crash! (I test it only on Android).
Hi Cristian,
Can you please provide a zip with the app in question?
Anders Lassen wrote:
Hi Cristian,
Can you please provide a zip with the app in question?
Is very similar to till@eightdaysaweek.cc app:
<App Theme="Basic">
<Panel>
<JavaScript>
var Observable = require('FuseJS/Observable');
var Camera = require('FuseJS/Camera');
var imageFile = Observable("");
function takePicture()
{
Camera.takePicture({ targetWidth: 200, targetHeight: 200, correctOrientation: true}).then(function(file)
{
convert( file );
})
.catch(function(e)
{
});
}
function convert( file )
{
var reader = new FileReader();
reader.onloadend = function()
{
imageFile.value = reader.result;
};
reader.readAsDataURL( file );
}
module.exports = {
takePicture : takePicture
}
</JavaScript>
<Button Height="48" Text="Take picture" Clicked="{takePicture}" />
</Panel>
</App>
Are there any news on this topic? I would love to implement user avatars in my app.
Thanks
Till
Hi Till, we have an open ticket on this but we might not get much done on it in the next 1-2 weeks. We’ll let you know when there’s any progress on this.
Same problem here… Any news?
Soon ready, I hope we can get it in one of the upcoming releases.
The file
that is given via the first parameter of camera.takePicture
can just have a toBase64()
method, that would make it easier for everyone:
camera.takePicture({...}, function(file) {
file.toBase64(); // returns base64 code
});
The File currently returned is one of these guys and we won’t extend that with arbitrary APIs.
This is actively being worked on at a day to day basis right now, I’ll keep this thread posted when things change. The next Camera API will require migration as it diverges a fair bit from the current one, though we’ll offer backwards compat.
That’s reasonable to not alter the Native Objects, how about passing a toBase64
method that takes a file object?
camera.takePicture({...}, function(file, toBase64) {
toBase64(file); // returns base64 code
});
The advantage is that readAsDataURL
doesn’t interact with fuse/uno/native (not sure which word is right), the same way camera.takePicture
does to open up the camera, so the toBase64
would use Uno’s native power
But anywho hopefully you guys figured something way better, but just a small suggestion
BTW an object helper would be better
camera.takePicture({...}, function(file, helper) {
helper.toBase64(file); // returns base64 code
});
So that it can have all types of methods and properties
Looking forward to this!
any update on this? my app is crashing using the file reader solution
function takePicture(){
camera.takePicture({targetWidth:100, targetHeight:100}).then(function(file){
var reader = new FileReader();
reader.onloadend = function() {
picture.value = reader.result;
console.log(reader.result);
};
reader.readAsDataURL(file);
}).catch(function(e){
console.log(e);
});
}
I also wanna know as well any update, but @Prince try to play with https://www.fusetools.com/docs/fusejs/base64
See if that helps and please let me know if you had any luck.