I understand that Android automatically creates a thumbnail, for every picture taken by the camera. I need to be able to display that thumbnail.
I'm using nativescript-imagepicker plugin to select images. The plugin returns only the size and src of the selected image(s), for instance:
'/storage/emulated/0/DCIM/DSCF2060.jpg'
How could i use this src, to retrieve the corresponding thumbnail(is it even possible?).
The Android API is very confusing for me(not to mention the Java), so any help will be greatly appreciated.
Use ThumbnailUtils
export function onGetImageButtonTap(args) {
let context = imagepicker.create({
mode: "single"
});
context
.authorize()
.then(function () {
return context.present();
})
.then(function (selection) {
selection.forEach(function (selected) {
const size = layout.toDevicePixels(96);
const bitmap = android.media.ThumbnailUtils.extractThumbnail(android.graphics.BitmapFactory.decodeFile(selected.android),
size, size);
args.object.page.getViewById("thumbnailImg").src = fromNativeSource(bitmap);
});
}).catch(function (e) {
console.log(e)
});
}
Playground Sample
Related
I am using react native and expo and the expo-image-picker is working great on iOs and mostly great on android with one exception. There is no "okay" or "select" or "done" button when a user pulls a picture from gallery.
The user has to click the crop button to accept the image. Is this typical? I feel like this will be confusing and a bad user experience...
const chooseImage = async (useCamera, index) => {
if (!(await checkPermission(useCamera))) {
Alert.alert(
"Permission missing.",
"Camera permission is required to take image."
);
return;
}
const method = useCamera ? "launchCameraAsync" : "launchImageLibraryAsync";
const result = await ImagePicker[method]({
allowsEditing: true,
base64: false,
aspect: [3, 4],
});
if (!result.cancelled) {
// upload image and retrieve image url
const {height, width, type, uri} = result;
profile.images[index] = uri;
if (uri != null) {
setProfile(profile);
}
setChangedValue("images");
}
};
UPDATE
Found that I can select the photo if I remove editing ability allowsEditing. But I want the user to be able to edit so I am curious why editing doesn't have an "okay" button on it?
I found that the crop button is the "done" button.
There is no other way to implement the selection of the image, so this is just a design aspect of the image picker.
I have been struggling for a few days with taking a photo with the phone camera, using Ionic and Android device, and sending it to the server in a post request. Optionally, I want to display the image to the screen.
I read a lot of previous posts with similar problems, but none of the solutions worked for me. I want to mention that I am quite new to the ionic world, so I am still learning. Maybe it is a stupid problem that I cannot see.
Before adding the code that I tried, I want to list the things that I have tried so far:
Used FILE_URL and DATA_URL for the destinationType option
Manually convert the image to base 64
Used domSanitizer.bypassSecurityTrustUrl(b64img) in the .html file
Please, see below the code that I tried:
This is the code for taking the photo:
const options: CameraOptions = { // photo options
quality: 50,
destinationType: this.camera.DestinationType.DATA_URL,
encodingType: this.camera.EncodingType.JPEG,
mediaType: this.camera.MediaType.PICTURE,
} // take picture
this.camera.getPicture(options).then((imageData) => {
this.imageData = imageData;
this.image = ( < any > window).Ionic.WebView.convertFileSrc(imageData);
//extra http://localhost/file.. and I slice it to remove extra chars
this.image = this.image.slice(27);
},
(err) => {
this.helperService.showAlert(JSON.stringify(err));
});
This is the code for uploading the photo to the server:
upload() { // upload method
let url = 'url/to/post';
const date = new Date().valueOf();
const imageName = date + '.jpeg';
console.log(this.imageData);
-- - > undefined
//slice it to remove extra chars
this.imageData = this.imageData.slice(27);
const imageBlob = this.dataURItoBlob(this.imageData);
const imageFile = new File([imageBlob], imageName, {
type: 'image/jpeg'
});
let postData = new FormData();
postData.append('file', imageFile);
let data: Observable < any > = this.httpClient.post(url, postData);
data.subscribe((result) => {
this.helperService.showSuccess(result);
});
}
And this is the blob function:
dataURItoBlob(dataURI) {
const byteString = window.atob(dataURI);
const arrayBuffer = new ArrayBuffer(byteString.length);
const int8Array = new Uint8Array(arrayBuffer);
for (let i = 0; i < byteString.length; i++) {
int8Array[i] = byteString.charCodeAt(i);
}
const blob = new Blob([int8Array], {
type: 'image/jpeg'
});
return blob;
}
This is my HTML file:
<ion-content>
<ion-grid>
<img [src]="DomSanitizer.bypassSecurityTrustUrl(image)">
</ion-grid>
<ion-button (click)="upload()" color="success">
<ion-icon slot="icon-only" name="checkmark"></ion-icon>
</ion-button>
</ion-content>
Problems:
The photo is not displayed on the screen and my image is Undefined - I tried both with and without DomSanitizer
this.imageData is undefined inside the upload() method
This is the reference post that I followed, but I cannot manage to see the problems:
Capture and upload image to server using Ionic 4
Looking at this reference post, I sliced even the extra characters displayed in front of the image, but I did not manage to solve the problems.
Let me know if I should add any other information. Thank you for your help!
I manage to display the image on the screen by using:
let b64 = 'data:image/jpeg;base64,' + imageData;
this.image = b64;
instead of
this.image = (<any>window).Ionic.WebView.convertFileSrc(imageData);
Unfortunately, this.imageData is still undefined, and I cannot figure out why.
Update: Looks like the photo is sent to bakend now, but its size is 0 and backend (which is Nodejs) cannot use it. What should I do? Should I parse it in some way?
Thank you!
I am trying to develop an android application using react-native. and one of the requirement is to automatically save the capture image based on pre-defined filename programmatically. I am using react-native-image-picker.
The API of image-picker does not show way to save the image with per-defined filename programmatically. The tutorial I am using, does not show either.
Thanks a lot.
I have done it like this. This may help you out.
ImagePicker.launchCamera({},(responce)=>{
this.setState({
pickedImage: { uri: res.uri }
});
console.log(this.state.serverTime);
const file ={
uri : responce.uri,
//give the name that you wish to give
name :this.state.currentTimeInMilisec+'.jpg',
method: 'POST',
path : responce.path,
type : responce.type,
notification: {
enabled: true
}
}
console.log(file);
})
}
I have done as below. It is working fine.
ImagePicker.launchCamera({},(responce)=>{
const localTime = new Date().getTime();
const file ={
uri : responce.uri,
//give the name that you wish to give
name :localTime +'.jpg',
method: 'POST',
path : responce.path,
type : responce.type,
notification: {
enabled: true
}
}
console.log(file);
})
}
Iam new in ionic with sharepoint
I have developed a Mobile app using ionic3 with sharepoint.
Now i have to get user profile picture in my app.
I have tried these are the way can't achieve here is my tried code.
First way tried like this
Passing Url:-
"https://abc.sharepoint.com/sites/QA/_layouts/15/userphoto.aspx?size=M&accountname=admin#abc.onmicrosoft.com"
Second way tried like this
Passing Url:-
These url iam geting using people picker result. PictureURL property
"https://abc.sharepoint.com/User Photos/Profile Pictures/admin_abc_onmicrosoft_com_MThumb.jpg"
These Second method always return
401 UNAUTHORIZED
Above url using to call this method.
public downloadFile(url: string, fileName: string) {
let options = this._apiHeaderForImageURL();
this._http.get(url, options)
.subscribe((data) => {
//here converting a blob to base 64 For internal view purpose in image src
var reader = new FileReader();
reader.readAsDataURL(data.blob());
reader.onloadend = function () {
console.log("Base64", reader.result);
}
//Here Writing a blob file to storage
this.file.writeFile(this.file.externalRootDirectory, fileName, data.blob(), { replace: true })
.then((success) => {
console.log("File Writed Successfully", success);
}).catch((err) => {
console.log("Error While Wrinting File", err);
});
});
}
public _apiHeaderForImageURL() {
let headers = new Headers({ 'Content-Type': 'image/jpeg' });
headers.append('Authorization', 'Bearer ' + localStorage.getItem("token"));
let options = new RequestOptions({ headers: headers, responseType: 3 });
return options;
}
The first api call worked fine result also sucess but image not displayed properly. Thats the problem iam facing.
The result comes an default image like this only.
pls help me to achieve this. Any help warmly accepted.
Iam doning long time stuff to achieve this still i cant achieve pls give some idea.
Is any other way is available to get user picture in ionic 3 using sharepoint?
I created a plugin using Picasso and it uses the android.widget.ImageView to load the cached image into.
The plugin works fine if using a Repeater but whenever i try using it with a ListView after scrolling past about the 7th item the ListView begins to reuse old images even if the image source is different
The reason why is because list views reuse the entire fragment; so what happens is that your img being reused gets the old image shown unless you clear it.
I actually use Picasso myself; and this is my current picasso library.
So if you look in my code below, when I set the new .url, I clear the existing image. (I made a comment on the specific line) -- This way the image now show blank, and then picasso loads it from either memory, disk or a remote url (in my case a remote url) and it will assign the proper image.
"use strict";
var Img = require('ui/image').Image;
var application = require("application");
var PT = com.squareup.picasso.Target.extend("Target",{
_owner: null,
_url: null,
onBitmapLoaded: function(bitmap, from) {
// Since the actual image / target is cached; it is possible that the
// target will not match so we don't replace the image already seen
if (this._url !== this._owner._url) {
return;
}
this._owner.src = bitmap;
},
onBitmapFailed: function(ed) {
console.log("Failed File", this._url);
},
onPrepareLoad: function(ed) {
}
});
Object.defineProperty(Img.prototype, "url", {
get: function () {
return this._url;
},
set: function(src) {
if (src == null || src === "") {
this._url = "";
this.src = null;
return;
}
var dest = src;
this._url = dest;
this.src = null; // -- THIS IS THE LINE TO CLEAR THE IMAGE
try {
var target = new PT();
target._owner = this;
target._url = dest;
var x = com.squareup.picasso.Picasso.with(application.android.context).load(dest).into(target);
} catch (e) {
console.log("Exception",e);
}
},
enumerable: true,
configurable: true
});
Please note you only need to require this class once, then it attaches itself to the <Image> component and adds the new .url property; this allows me to use this in the Declarative XML in all the rest of the screens and when I need picasso, I just use the .url property to have picasso take over the loading of that image.