I have developed an app to take a photo from the phone camera. But now I need to store the image to the phone memory into a folder created by me.
I have tried this:
var filename = Titanium.Filesystem.resourcesDirectory + "/newImageFile.jpg";
var imageFile = Titanium.Filesystem.getFile(filename);
imageFile.write(capturedImg);
But it does not apear in the gallery. How can I store the image to the phone memory and how can I create a costume folder in the phone memory to store the image?
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info
{
NSData *imageData = [info objectForKey:UIImagePickerControllerOriginalImage];
if(picker.sourceType==UIImagePickerControllerSourceTypeCamera)
{
//to save camera roll
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
[PHAssetChangeRequest creationRequestForAssetFromImage:image];
} completionHandler:nil];
}
}
This will save image in camera roll which is taken by you
This Will Create Photo Album and save into this album.
I came up with this singleton class to handle it:
import Photos
class CustomPhotoAlbum {
static let albumName = "Titanium"
static let sharedInstance = CustomPhotoAlbum()
var assetCollection: PHAssetCollection!
init() {
func fetchAssetCollectionForAlbum() -> PHAssetCollection! {
let fetchOptions = PHFetchOptions()
fetchOptions.predicate = NSPredicate(format: "title = %#", CustomPhotoAlbum.albumName)
let collection = PHAssetCollection.fetchAssetCollectionsWithType(.Album, subtype: .Any, options: fetchOptions)
if let firstObject: AnyObject = collection.firstObject {
return collection.firstObject as! PHAssetCollection
}
return nil
}
if let assetCollection = fetchAssetCollectionForAlbum() {
self.assetCollection = assetCollection
return
}
PHPhotoLibrary.sharedPhotoLibrary().performChanges({
PHAssetCollectionChangeRequest.creationRequestForAssetCollectionWithTitle(CustomPhotoAlbum.albumName)
}) { success, _ in
if success {
self.assetCollection = fetchAssetCollectionForAlbum()
}
}
}
func saveImage(image: UIImage) {
if assetCollection == nil {
return // If there was an error upstream, skip the save.
}
PHPhotoLibrary.sharedPhotoLibrary().performChanges({
let assetChangeRequest = PHAssetChangeRequest.creationRequestForAssetFromImage(image)
let assetPlaceholder = assetChangeRequest.placeholderForCreatedAsset
let albumChangeRequest = PHAssetCollectionChangeRequest(forAssetCollection: self.assetCollection)
albumChangeRequest.addAssets([assetPlaceholder])
}, completionHandler: nil)
}
}
When you first instantiate the class, the custom album will be created if it doesn't already exist. You can save an image like this:
CustomPhotoAlbum.sharedInstance.saveImage(image)
NOTE: The CustomPhotoAlbum class assumes the app already has permission to access the Photo Library. Dealing with the permissions is a bit outside the scope of this question/answer. So make sure PHPhotoLibrary.authorizationStatus() == .Authorize before you use it. And request authorization if necessary.
Related
I am having a problem with uploading an image in ios apollo client. after I upload an image I get a GraphQlError "createReadStream is not a function".
I could not figure out what has gone wrong?
Mutation
mutation UploadPhoto($input: UploadPhotoInput){
uploadClientPhoto(input: $input){
photo
}
}
Type Detail
type UploadPhotoInput {
photo: Upload
}
type UploadPhotoResponse {
photo: String
}
Following code is not working
class Network {
static let shared = Network()
private lazy var networkTransport = HTTPNetworkTransport(url: URL(string: "http://192.168.10.29:5001/graphql")!, session: .init(configuration: URLSessionConfiguration.default))
private(set) lazy var apolloCient = ApolloClient(networkTransport: networkTransport)
}
Upload image
if let data = singlePhoto.image.jpegData(compressionQuality: 0.8) {
let name = UUID().uuidString
let file = GraphQLFile(fieldName: "\(name)", originalName: "\(name).png",mimeType: "image/png" ,data: data)
let uploadInput = UploadPhotoInput(photo: file.originalName)
let uploadMutation = UploadPhotoMutation(input: uploadInput)
Network.shared.apolloCient.upload(operation: uploadMutation, context: nil, files: [file]) { (result) in
switch result {
case .success(let success):
print(success.data)
case .failure(let error):
print(error.localizedDescription)
}
}
}
This certainly sounds frustrating. I've heard of similar issues with other networking clients, though.
Sounds like apolloCient.upload won't send a GraphQL Multipart Request.
Looks like this blog post covers exactly how to set this up - even including an example repo made for React Native.
Hope that's helpful!
I am using xamarin forms and build sample app. The app has few fields and take image function. When user take an image, the image get saved in phone gallery and get renamed to data from fields.
I have a notes field. In notes field user can enter some text and characters. I don't want to include data from note fields to rename image.
What I want is to get the user input from notes field and save in image comments. (Please see image below).
image comment
My first question is it possible to do that. So user fill some fields, take picture, and whatever user type in notes field; it can get saved in imagedetails->comments.
This is code to save image and rename to some data input fields.
I am using jamesmontemagno/MediaPlugin plugin to take images.
https://github.com/jamesmontemagno/MediaPlugin
private async void Take_Photo_Button_Clicked(object sender, EventArgs e)
{
await CrossMedia.Current.Initialize();
if (!CrossMedia.Current.IsCameraAvailable || !CrossMedia.Current.IsTakePhotoSupported)
{
await DisplayAlert("No Camera", ":( No camera available.", "OK");
return;
}
var file = await CrossMedia.Current.TakePhotoAsync(new Plugin.Media.Abstractions.StoreCameraMediaOptions
{
SaveToAlbum = true,
//Directory = "Sample",
Name = jobnoentry.Text + "-" + Applicationletter + "-" + signnoentry.Text + "-" + Phototypeentry,
});
if (file == null)
return;
MainImage.Source = ImageSource.FromStream(() =>
{
var stream = file.GetStream();
return stream;
});
You can see I assign Name of image to some data fields. But how i can add notes to annotate the image and have them in image comments.
Hope you all understand my question.
It's not clear what file type is the image being stored as. Is it a .png? a .jpeg? The library's example seems to indicate it stores JPEG files.
If that's the case, look into editing EXIF data. i.e. https://developer.xamarin.com/api/type/Android.Media.ExifInterface/
I can't seem to get the url, from the PlacePhotoMetadata object. Debugger shows that there is an URL there but I can't seem to access it.
How do you access the URL in the object?
val placeId = "ChIJa147K9HX3IAR-lwiGIQv9i4"
val photoMetadataResponse = mGeoDataClient.getPlacePhotos(placeId)
photoMetadataResponse.addOnCompleteListener { task ->
// Get the list of photos
val photos = task.result
// Get the PlacePhotoMetadataBuffer (metadata for all of the photos)
val photoMetadataBuffer = photos.photoMetadata
// Get the first photo in the list
for (photo in photoMetadataBuffer) {
// Get the attribution text
val attribution = photo.attributions
}
}
You can't. Take a look at the documentation for PlacePhotoMetadata. There are methods to download a bitmap of the image, but no methods that return the URL.
To get the photo you should do something like this:
// this is your for-loop:
photoMetadataBuffer.forEach { photo ->
photo.getPhoto(client).setResultCallback({ result ->
// do whatever you want here:
showPhotoWithAttribution(photo.attributions, result.getBitmap())
})
}
Note that replacing a for-loop with a forEach call has no real advantage, it just makes your code look cleaner.
I am trying to create an Android application created using Adobe Flash Actionscript 3. I wanted each user of the app to input their name in the beginning of the application, then they have the capability to save their progress in current frame (and it will be saved into a save slot or similar). However, the problem arises when another user is going to use the app, he/she must enter a distinct username, and he/she can save anytime (and load his/her distinct load progress, different from the previous user.). And it goes on.
I am a newbie in programming and I hope you could help me. Any suggestions will be appreciated. Thanks!
This my code for creating a username and saving it:
function handleClick(Event:MouseEvent):void
{
var myFirstVariable = boxOne.text;
boxTwo.text = myFirstVariable;
gotoAndStop("opening_scene")
}
myButton2.addEventListener(MouseEvent.MOUSE_UP, handleClick);
UPDATED EDIT 2: Here is my code for saving and loading. Still not working:
var so:SharedObject = SharedObject.getLocal("Test");
var userName:String = nameField.text;
if (so.data.users == null)
so.data.users = new Object();
btnSave.addEventListener(MouseEvent.CLICK, onClick);
function onClick(e:MouseEvent):void
{
if (so.data.users[userName] == null)
so.data.users[userName] = new Object();
so.data.users[userName].lastframe = currentFrame;
so.flush();
trace(userName);
}
btnLoad.addEventListener(MouseEvent.CLICK, reloadBtnClick);
function reloadBtnClick(e:MouseEvent):void
{
if (so.data.users[userName] == null)return;
if (so.data.users[userName].lastFrame == null) return;
gotoAndStop(so.data.users[userName].lastFrame);
trace(userName);
}
I recommend that you use a SQLite Data Base to save your data can find all the documentation here Manipulating SQL database data Well is a little bit more complicate but works like have tables in Excel.
As Vesper suggested, you need to have a storage with all the users you store. For example:
// Put user name here.
var userName:String;
var SO:SharedObject = SharedObject.getLocal("save");
// Create storage for users.
if (SO.data.users == null) SO.data.users = new Object();
// ...
function saveCurrentFrame(event:MouseEvent):void
{
// Create storage for current user by their name.
if (SO.data.users[userName] == null) SO.data.users[userName] = new Object();
SO.data.users[userName].lastframe = currentFrame;
SO.flush();
}
function getLastFrame(event:MouseEvent):void
{
trace(1);
// Skip this if there's no record for
if (SO.data.users[userName] == null) return;
trace(2);
if (SO.data.users[userName].lastFrame == null) return;
trace(3);
gotoAndStop(SO.data.users[userName].lastFrame);
trace(4);
}
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.