Jump to content
Sign in to follow this  
IElite

Working with images in the file system? 

Recommended Posts

I now have the need to add this functionality to my app. Before I begin, just curious if anyone has already accomplished all or any of these steps?

 1.) Select an image from the file system
 2.) Display the image in a TW3Image or HTML DIV / Element
 3.) Save image from step 2 on application termination (or form deactivation)
 4.) Load image from step 2 on application start up (or form activation)
 5.) Add steps 1-4 dependent on browser/platform (esp. Android / iOS)

 

and would be willing to share?
 

Share this post


Link to post
Share on other sites

Is this a phonegap-app? And are the images camera photos?

Well, assuming it is, use a file picker plugin to select the image. For example, this one: https://github.com/ourcodeworld/cordova-ourcodeworld-filebrowser

To use that picker, you need to add this to Phonegap's config.xml:

<plugin name="com.ourcodeworld.plugins.Filebrowser" spec="https://github.com/ourcodeworld/cordova-ourcodeworld-filebrowser.git" />

And in Smart you call this one:

procedure TForm1.OpenPickDialog(Sender: TObject);
//  Uses https://github.com/ourcodeworld/cordova-ourcodeworld-filebrowser

  procedure DoLoad(data: Variant);
  begin
    MyImage.LoadFromUrl(data);
  end;

begin
  asm
    window.OurCodeWorld.Filebrowser.filePicker.single({
      success: function(data) {
        @DoLoad(data);
      },
      error: function(data) {
        @FileDialogError(data); //Handler for errors
      }
    });
  end;
end;

That's steps 1 and 2. For iOS you just need to use a different plugin.

The saving then... I haven't tested that yet, but I suppose you can use TW3Image.ToStream to save it to a stream. After that it's a matter of calling Phonegap's save functions. Here's some code that I used to save a push notification token to a file:

procedure TForm1.SavePushToken(NewFileName: String);
var NewFilePath: String;

  procedure fail(err: Variant);
  begin
    AddToLog('Error saving push notification token');
  end;

  procedure FileWriterCreated(FileWriter: Variant);
  begin
    var TokenToWrite := PhoneGap.RegistrationId;
    asm
      FileWriter.onerror = @fail;
      FileWriter.write(@TokenToWrite);
    end;
  end;

  procedure FileCreated(fileEntry: Variant);
  begin
    AddToLog('File created');
    asm
      fileEntry.createWriter(@FileWriterCreated);
    end;
  end;

  procedure onDirectorySuccess(dirEntry: Variant);
  begin
    AddToLog('Got directory access');
    asm
      dirEntry.getFile(NewFileName, {create: true, exclusive: false}, @FileCreated, @fail);
    end;
  end;

begin
  AddToLog('Saving push notification token');
  //Split NewFileName to path and file
  for var a:=Length(NewFileName) downto 1 do
    if NewFileName[a]='/' then begin
      NewFilePath := copy(NewFileName,1,a);
      NewFileName := copy(NewFileName,a+1,Length(NewFileName));
      break;
    end;
  asm
    window.resolveLocalFileSystemURL(@NewFilePath, @onDirectorySuccess);
  end;
end;

BTW, the file picker does NOT work in Phonegap desktop app. You need a proper phonegap/cordova environment or Phonegap Build.

Share this post


Link to post
Share on other sites
On 12/03/2018 at 10:54 AM, IElite said:

I now have the need to add this functionality to my app. Before I begin, just curious if anyone has already accomplished all or any of these steps?

 1.) Select an image from the file system
 2.) Display the image in a TW3Image or HTML DIV / Element

@lynkfs helped me with this procedure:

 edPhoto1.InputType := itFile;
  edPhoto1.Handle.ReadyExecute( procedure ()
    begin
      w3_setAttrib(edPhoto1.Handle, 'accept', 'image/*');
      w3_setAttrib(edPhoto1.Handle, 'capture', '');

      edPhoto1.OnChanged := procedure(sender:TObject)
        begin
          var reader: variant;
          asm @reader = new FileReader(); end;
          reader.onload := lambda imgPhoto1.handle.src := reader.result; end;
          reader.readAsDataURL(edPhoto1.handle.files[0]);
        end;
    end);
 

Share this post


Link to post
Share on other sites

And shorter without asm:

  edPhoto1.InputType := itFile;
  edPhoto1.Handle.ReadyExecute( procedure ()
    begin
      w3_setAttrib(edPhoto1.Handle, 'accept', 'image/*');
      w3_setAttrib(edPhoto1.Handle, 'capture', '');

      edPhoto1.OnChanged := procedure(sender:TObject)
        begin
          var reader := JFileReader.Create;
          reader.onload := lambda imgPhoto1.handle.src := reader.result; end;
          reader.readAsDataURL(JBlob(edPhoto1.handle.files[0]));
        end;
    end);

 

 

Share this post


Link to post
Share on other sites

@DidierXT

I get a "Uncaught TypeError: Cannot read property '0' of undefined  [line #16957]"

procedure TForm1.InitializeObject;
begin
  inherited;
  {$I 'Form1:impl'}

  W3EditBox1.InputType := itFile;
  W3EditBox1.Handle.ReadyExecute( procedure ()
    begin
      w3_setAttrib(W3EditBox1.Handle, 'accept', 'image/*');
      w3_setAttrib(W3EditBox1.Handle, 'capture', '');

      W3EditBox1.OnChanged := procedure(sender:TObject)
        begin
          var reader := JFileReader.Create;
          reader.onload := lambda W3Image1.handle.src := reader.result; end;
          reader.readAsDataURL(JBlob(W3Image1.handle.files[0]));
        end;
    end);

end;

am i missing something  else?

Share this post


Link to post
Share on other sites

acutally, i found the problem,

i had reader.readAsDataURL(JBlob(W3Image1.handle.files[0]));

instead of what i should have had

reader.readAsDataURL(JBlob(W3EditBox1.handle.files[0]));

:)

 

Thanks

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×