I am developing a phoneGap application in IOS where I use getPhoto('Camera.PictureSourceType.PHOTOLIBRARY');
to access the photo library and select an image. following is the onPhotoURISuccess method where I need to get the url of the image and pass it to my native plugin to validate it's filesize, resolution and file extension.
this is my getPhoto() method
// A button will call this function
function getPhoto(source)
{
// Retrieve image file location from specified source
navigator.camera.getPicture(onPhotoURISuccess, onFail, { quality: 100,
destinationType: navigator.camera.DestinationType.NATIVE_URI, sourceType: source });
}
and this is the onPhotoURISuccess method,
// Called when a photo is successfully retrieved
function onPhotoURISuccess(imageURI)
{
img_uri = imageURI;
console.log('NATIVE_URI==>'+img_uri);
// Get image handle
var imgPrev = document.getElementById('imgPreview');
// Unhide image elements
imgPrev.style.display = 'block';
// Show the captured photo
// The inline CSS rules are used to resize the image
imgPrev.src = imageURI;
}
I have three options for this according to the phoneGap documentation. using DATA_URL, FILE_URI or NATIVE_URI.
FILE_URI seems to be hiding underlying data of the image where it always returns me a jpeg image thus the actual extension is hidden
assets-library://asset/asset.JPG?id=5CF16D20-9A80-483A-AC1C-9692123610B1&ext=JPG
I want to know how to get the actual image name along with the extension from this.
I need to get the image name and validate the extension.
someone please do help me with posssible approach for me to follow
thanks in advance
If you could get an url to asset, which is
assets-library://asset/asset.JPG?id=5CF16D20-9A80-483A-AC1C-9692123610B1&ext=JPG
You can get real name of file, by this asset:
NSString* originalFileName = [[yourALAsset defaultRepresentation] filename];
Related
How can I pick images directly as jpg or png on iOS?
If this feature isn't available: How can I convert it very fast and don't have to wait a long time?
Edit: I want to prevent picking .heic because I have to send it to an server, which handles jpg and png and not .heic
Thanks to Mohammad Assad Arshad!
It can be solved by pub.dev/packages/file_picker.
An additional explanation:
https://pub.dev/packages/file_picker allows you to pick files/images etc. and the file type of images is .jpg
https://pub.dev/packages/multi_image_picker allows you to pick images too, but takes the original file format; e.g. .heic, .jpg, .png
i select images with filepicker https://pub.dev/packages/file_picker
FilePickerResult result;
try {
result = await FilePicker.platform.pickFiles(
type: FileType.custom,
allowedExtensions: ['jpeg', 'jpg', 'heic', 'pdf'],
);
} catch (e) {
print('Exep: ****${e}***');
}
now you can check the extention of the file, use the package path.dart as p and package https://pub.dev/packages/heic_to_jpg to convert image to jpeg
File file = File(result.files.first.path);
String fileExtension = p.extension(file.path).replaceAll('.', '');
if (fileExtension == 'heic') {
print('convert to jpeg');
String jpegPath = await HeicToJpg.convert(file.path);
file = File(jpegPath);
fileExtension = 'jpeg';
}
do not forget do the same if you use imagePicker with source camera.
you can use multi_image_picker 4.6.7 to pick image in iOS for HEIC images.
I have silly problem with loading image from the file. I have two views putted to UITabBarController.
At the first view user can load his image from the Photo Library or Camera. Second view present this photo. This file is on the server. If user doesn't choose his image server sent custom image. If there is uploaded photo it will push user's picture.
When user tap button there is a menu with options. For example we will decide to take picture from the Photo Library. After user took image:
func imagePickerController(picker: UIImagePickerController, didFinishPickingImage image: UIImage!, editingInfo: [NSObject : AnyObject]!) {
self.saveUserImage(userID, imageData: UIImagePNGRepresentation(image)!)
apiManager.userUploadProfile(userID, imageData: UIImagePNGRepresentation(image)!)
userImageView.image = image
}
func saveUserImage(userUUID: String, imageData: NSData) {
let path = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true).last
let savePath = path! + "/\(userUUID)-user.png"
NSFileManager.defaultManager().createFileAtPath(savePath, contents: imageData, attributes: nil)
}
After that point user can see chosen picture and everything is okey. When user change tab, second view will refresh all data on it and again will download all images and data from the server. Unfortunately images that contains old user image doesn't refresh and there is still old photo.
When we come back to the first tab image is going back to old image but after few seconds.
The strangest thing is if I am checking server there is new uploaded image and in the app container it exist too. When I restart the app everything works perfectly.
It looks like this image is saved in the memory and iOS takes old version from RAM or from some other swap. How refresh UIImageView and show current saved image?
EDIT:
There is a method which load the image
func userProfilePicture(userId: String) -> UIImage {
let cacheDirectory = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true).last
let savePath = cacheDirectory! + "/\(userId)-user.png"
if NSFileManager.defaultManager().fileExistsAtPath(savePath) {
if let image = UIImage(named: savePath) {
return image
}
}
return UIImage(named: "test_avatar")!
}
I can't comment but i was facing a similar issue but i have a question, does the picture get uploaded before the user changes tabs, or after? Even if you call the function to update the database, it takes some time to actually "send the new photo/path to the photo to the database". Here are your options, if the picture is not in the server at the time of the switching tabs, implement a loading ui until it has successfully uploaded and the new, updated value, into the database. An easy way to do that would be to use the SVProgressHUD pod and set the default mask type to .clear which disables user interaction. Option 2, is to pass the actual UIImage via a static variable, or in the prepare for segue method, or through a struct, or any other way and set the picture that needs to be refreshed to the uiimage without getting it from the server only when you switch tabs.
Okey, I found the answer. The problem was in initialize UIImage. We have two methods to load image from file.
First one load the image and cache it in memory. Later it use only a reference to this image data in memory:
let image = UIImage(named: savePath)
Second method load image strictly from file every time when user use that function:
let image = UIImage(contentsOfFile: savePath)
Right now it works perfectly :D
I need to make a video file from thousands of images generated by code.
I cannot put those images into an array because they are too many--a 30second-long video would consist of 1800 imgae frames. And I don't get all images at once.
To get each image, it first triggers Javascript fucntion in WebView asking if a video frame,which is UIImage, should be generated. if Yes, my code makes UIImage for a video frame one at a time. and the app does other things and at some point it asks webview again for a permission to generate another image. it does this for a thousand times and more.
If Delegate gets a message that says No, the last image was a final video frame so a complete video file should be made at this point and saved to Document directory.
How should I do this? Objective C solutions would be acceptable too. thank you in advance
//ask webview if another video frame should be made
func askWebView() {
webView?.evaluateJavaScript("Ask JS function",completionHandler:nil)
}
Delegate
//Delegate method
func userContentController(userContentController:WKUserContentController,didReceiveScriptMessage message:WKScriptMessage){
let body:String = message.body as! String
if body == "makeAFrame" {
let videoFrame = self.makeImage()
//should asseble video frames
} else {
//No,nomore video frame. write a complete video file to Document directory
}
Generating an UIImage for a video frame
func makeImage() -> UIImage {
//make an image and return it
}
Hey so I'm trying to have a button that when pressed allows the user to choose 2-5 pictures from their photo library then have whatever photo chosen be set onto a uiimageview? I was looking online and couldn't find anything related to how to do it in swift?
Thanks
I worked out using this : https://github.com/zhangao0086/DKImagePickerController .
Getting selected image's thumbnail images:
let pickerController = DKImagePickerController()
pickerController.sourceType = .Photo
pickerController.didCancelled = { () in
println("didCancelled")
}
pickerController.didSelectedAssets = { [unowned self] (assets: [DKAsset]) in
println("didSelectedAssets")
println(assets)
for(var i = 0; i<(assets.count); i++){
print(assets[i].url)
self.PickedArray .addObject(assets[i].thumbnailImage!)
}
self.performSegueWithIdentifier("SegueToPhotoLibraryView", sender: self)
Getting selected image's urls :
assets[i].url instead of assets[i].thumbnailImage
Hope it helps!
Currently iOS does not provide an image picker out of the box that lets you pick multiple images from the photo library. UIImagePickerController only lets you select one image.
But there are several image picker implementations available that let you pick multiple images. You can find a whole bunch at cocoacontrols.com as #ytbryan already mentioned.
I am currently not aware of any multiple image picker implemented in Swift. If someone finds one, please edit and post the link.
Titanium / for an iOS App:
How can I manage to take a photo, and then use this one later in a new function to for example show the photo, and put a slightly larger duplicate of it with a transparency on top of itself?
Note that I tried to edit the answer from Mitul Bhalia with the following, but the edit got knocked back. So here's how you do it:
After taking the image, you can store it as a variable in the global object, Alloy.Globals. You can then access this else where or later on in your app.
For example:
takePhotoButton.addEventListener('click', function(){
Titanium.Media.showCamera({
success:function(event) {
if(event.mediaType === Ti.Media.MEDIA_TYPE_PHOTO) {
// Store the file in a variable
var image = event.media;
// Store the image in the global object
Alloy.Globals.temporaryImage = image;
} else {
alert("got the wrong type back ="+event.mediaType);
}
},
...
And somewhere else in your app, after the image has been stored, for example:
var anImage = Ti.UI.createImageView({ image: Alloy.Globals.temporaryImage })
Also note that extensive use of the global object can cause memory issues, so try not to overdo it.
If you want to save photo then you can use Alloy.Globals to save data globally so you can use it later.
Alloy.Globals.photo = blob object;
Here is how I am currently solving my problem:
takePhotoButton.addEventListener('click', function(){
Titanium.Media.showCamera({
success:function(event) {
if(event.mediaType === Ti.Media.MEDIA_TYPE_PHOTO) {
// Store the file in a variable
var image = event.media;
var filename = 'myPhoto.jpg';
takenPhoto = Titanium.Filesystem.getFile(Titanium.Filesystem.applicationDataDirectory, filename);
takenPhoto.write(image);
} else {
alert("got the wrong type back ="+event.mediaType);
}
},
...
and then later I can use takenPhoto to show the picture I have taken with the camera.
But I do not really know if this is the best way and if it is even correct, as I do not use 'var' to initiate takenPhoto. But if I use 'var' I cannot use takenPhoto outside of the function.