How to convert a picture path to mediafile?

SreeeeSreeee INMember ✭✭✭✭✭

I have a picture file path and I am trying to upload this picture to server. When I upload this picture to server I need it's GetStream() value. I will show a sample code, that I have used in another place:

var content = new MultipartFormDataContent();
content.Add(new StreamContent(_mediaFile.GetStream()), "\"file\"", $"\"{_mediaFile.Path}\"");
var response = await httpClient.PostAsync(new Uri("My REST API"), content);

if (response.IsSuccessStatusCode)
{
   //Success
}

Where _mediaFile is a MediaFile

private MediaFile _mediaFile;

But currently, I have only the picture path. So is there any way to convert the picture path to MediaFile or anyway way to get the GetStream() value of the picture path?

Best Answers

  • LandLuLandLu Xamurai
    Accepted Answer

    @Sreeee About how to retrieve data from the project, I have posted the corresponding code in my sample above:

    var myStr = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
    var filePath = Path.Combine(myStr, "charm.png");
    
    var assembly = System.Reflection.Assembly.GetExecutingAssembly();
    
    string targetStr = null;
    if (Device.RuntimePlatform == Device.iOS)
    {
        targetStr = "iOS";
    }
    else if (Device.RuntimePlatform == Device.Android)
    {
        targetStr = "Droid";
    }
    else
    {
        targetStr = "UWP";
    }
    
    using (var stream = assembly.GetManifestResourceStream("App3." + targetStr + ".charm.png"))
    {
        byte[] buffer = new byte[stream.Length];
        stream.Read(buffer, 0, buffer.Length);
        File.WriteAllBytes(filePath, buffer);
    }
    

    The file's build action should be Embedded resource, and use the code below to check what resources you could use in current assembly:
    assembly.GetManifestResourceNames();

Answers

  • ClintStLaurentClintStLaurent USUniversity ✭✭✭✭✭

    Stream isn't a different path.
    Its not a different file on the device.
    You read the file into a memory stream then provide that object.

    https://social.msdn.microsoft.com/Forums/vstudio/en-US/b3aa9965-9947-4003-b1e1-57353f083e38/how-to-convert-image-files-to-stream?forum=csharpgeneral

  • ClintStLaurentClintStLaurent USUniversity ✭✭✭✭✭
    edited January 2019
  • SreeeeSreeee INMember ✭✭✭✭✭

    @ClintStLaurent Can you please look the following screenshot. Where picturepath is the path of the image.
    Sample path: C:\Users\sonub\AppData\Local\Packages\com.pagematics.listpmcustomer_hcgbetyqs63kp\LocalState\business-process - Copy (7).jpg

  • SreeeeSreeee INMember ✭✭✭✭✭

    In the accepted answer of this thread where we are providing the picture path?

    Try using xamarin.forms lab.
    https://github.com/XLabs/Xamarin-Forms-Labs/wiki/Camera
    ImageSource = ImageSource.FromStream(() => mediaFile.Source);
    mediaFile.Source is your stream, hope it helps.

  • ClintStLaurentClintStLaurent USUniversity ✭✭✭✭✭

    @Sreeee said:
    @ClintStLaurent Can you please look the following screenshot. Where picturepath is the path of the image.
    Sample path: C:\Users\sonub\AppData\Local\Packages\com.pagematics.listpmcustomer_hcgbetyqs63kp\LocalState\business-process - Copy (7).jpg

    That is clearly a screwed up example. I wouldn't bother trying to follow any example that codes like that.
    Notice how there is no MVVM being used...
    The code which should be from a ViewModel is directly grabbing text out of the UI Entry - sheesh

    C:\Users\sonub\AppData\Local\Packages\com.pagematics.listpmcustomer_hcgbetyqs63kp\LocalState\business-process - Copy (7).jpg

    Are yo making a Windows application? Because that's a Windows path.
    Is it a valid path? Have yo double checked? Is that really the user name for example? Does your code check to see if the file exists before trying to use it?

  • SreeeeSreeee INMember ✭✭✭✭✭

    @ClintStLaurent I am making a xamarin forms application, I send a windows path because I run windows app to get a sample path. File exist before and after the use.

  • ClintStLaurentClintStLaurent USUniversity ✭✭✭✭✭

    Ok. Next part of your post to tackle.

    So is there any way to convert the picture path to MediaFile

    What do you mean by that? What do you mean 'convert the picture to a mediafile'? Do you think MediaFile is a file type: Something you can convert to/from?

  • SreeeeSreeee INMember ✭✭✭✭✭

    Look the following function to open a camera, here I am using _mediaFile for storing a picture. Using that _mediaFile I am uploading the image to server. Mediafiles have GetStream() property so that I can upload that file to the server using that property. I think MediaFile is a type of file we can convert to/from, that's why I asked like that.

    public async void OpenMyCamera()
        {
            try
            {
                await CrossMedia.Current.Initialize();
    
                if (!CrossMedia.Current.IsCameraAvailable || !CrossMedia.Current.IsTakePhotoSupported)
                {
                    await DisplayAlert("Alert", "No camera available.", "Ok");
                    return;
                }
    
                _mediaFile = await CrossMedia.Current.TakePhotoAsync(new Plugin.Media.Abstractions.StoreCameraMediaOptions
                {
                    Directory = "Sample",
                    Name = "test.jpg",
                    AllowCropping = true
                });
    
                if (_mediaFile == null)
                    return;
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine("Exception:>" + ex);
            }
        }
    
  • SreeeeSreeee INMember ✭✭✭✭✭

    @LandLu I am working on xamarin forms PCL project. In this type of projects, File is not available. So I can't use the below code.

    var bytes = File.ReadAllBytes(filePath);
    
  • LandLuLandLu Member, Xamarin Team Xamurai

    @Sreeee System.IO.File can be used in Xamarin.Forms project. Try to involve the space name using System.IO;.
    Or use the whole name.

  • seanydaseanyda GBMember ✭✭✭✭✭

    @Sreeee said:
    @LandLu I am working on xamarin forms PCL project. In this type of projects, File is not available. So I can't use the below code.

    var bytes = File.ReadAllBytes(filePath);
    

    It is if you use the DependencyService to write the code, It's just not available in the shared library.

    https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/dependency-service/introduction

  • SreeeeSreeee INMember ✭✭✭✭✭
    edited January 2019

    @LandLu I already tried both and no luck. See this.

  • SreeeeSreeee INMember ✭✭✭✭✭
    edited January 2019

    @seanyda Yes I am working on select multiple images from gallery feature and it is using DependencyService. Is there any solution for this?

  • LandLuLandLu Member, Xamarin Team Xamurai
    edited January 2019

    @Sreeee I created a sample for you, you can check the attachment for detailed code.
    My Forms library maybe exists some error. If you want to build this sample, remove the Xamarin.Forms library on each platform and add it again.

  • SreeeeSreeee INMember ✭✭✭✭✭

    I will go through this and update you @LandLu
    Thanks in advance :)

  • SreeeeSreeee INMember ✭✭✭✭✭

    @LandLu said:
    @Sreeee I created a sample for you, you can check the attachment for detailed code.
    My Forms library maybe exists some error. If you want to build this sample, remove the Xamarin.Forms library on each platform and add it again.

    This is a .Net standard project, right? In your sample, File is working.

    Is there any other way to resolve this issue without converting to .Net standard? When I convert getting a lot of errors. I am using this for converting PCL to .Net standard.

  • ClintStLaurentClintStLaurent USUniversity ✭✭✭✭✭

    Well... Either start a new project that's .NET Standard, or work through the issues. But PCL has been deprecated for at least 2 years now. You really want to get up to date sooner rather than later.

  • LandLuLandLu Member, Xamarin Team Xamurai

    @Sreeee .NET Framework has many limitations of api usage due to different profile numbers. We highly recommend you to use .NET Standard libraries. And PCLs are considered deprecated in the latest versions of Visual Studio.
    It's not a difficult thing to convert your project to .NET Standard, as almost all of the .NET Framework's apis are supported in .NET Standard.

  • SreeeeSreeee INMember ✭✭✭✭✭

    @LandLu, @NMackay @ClintStLaurent Thanks for the suggestions, I will convert the project to .Net standard or create a new .Net standard project and add all my files and icons into it.

  • SreeeeSreeee INMember ✭✭✭✭✭

    hi @LandLu, @NMackay @ClintStLaurent

    One quick question. I created a new .Net standard project and add the upload picture part only. I hard coded the picture path like below in my project.

     var fileBytes = File.ReadAllBytes("C:/testpic.jpg");
    

    But getting an exception:

    Exception thrown: 'System.UnauthorizedAccessException' in System.Private.CoreLib.dll
    Exception1:>System.UnauthorizedAccessException: Access to the path 'C:\testpic.jpg' is denied.
       at System.IO.FileStream.ValidateFileHandle(SafeFileHandle fileHandle)
       at System.IO.FileStream.CreateFileOpenHandle(FileMode mode, FileShare share, FileOptions options)
       at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options)
       at System.IO.File.InternalReadAllBytes(String path)
       at System.IO.File.ReadAllBytes(String path)
       at Listpm.MainPage.<CallUploadREST>d__1.MoveNext()
    

    Worked on windows app and I added photo library permission in package.appxmanifet

  • SreeeeSreeee INMember ✭✭✭✭✭

    @LandLu, @NMackay @ClintStLaurent

    Please suggest the best way of converting PCL to .Net Standard?

  • LandLuLandLu Member, Xamarin Team Xamurai

    @Sreeee I'm afraid you added the wrong permission.
    Refer to this documentation: https://docs.microsoft.com/en-us/windows/uwp/files/file-access-permissions
    We know that the default system locations app can reach is:

    1. Project package directory
    2. Application data folder

    If you want to access additional locations, you should use open file picker or add special permission. Then use Windows.Storage to achieve that: https://docs.microsoft.com/en-us/windows/uwp/files/file-access-permissions#accessing-additional-locations.
    I don't recommend you to do that: https://blogs.msdn.microsoft.com/wsdevsol/2012/12/04/skip-the-path-stick-to-the-storagefile/. So I used Environment.GetFolderPath to get the application data folder in my sample.

  • SreeeeSreeee INMember ✭✭✭✭✭
    edited January 2019

    @LandLu I have added the same picture in the project directory, tried like below.

            var myStr = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
                var filePath = Path.Combine(myStr, "testpic.jpg");
                var fileBytes = File.ReadAllBytes(filePath); );
    
  • LandLuLandLu Member, Xamarin Team Xamurai

    @Sreeee I think this thread should be closed. If you want to know more information about converting PCL to .NET Standard, you could open a new case. Describe the detailed errors you are facing.
    Then we can find an appropriate workaround there.

  • LandLuLandLu Member, Xamarin Team Xamurai
    Accepted Answer

    @Sreeee About how to retrieve data from the project, I have posted the corresponding code in my sample above:

    var myStr = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
    var filePath = Path.Combine(myStr, "charm.png");
    
    var assembly = System.Reflection.Assembly.GetExecutingAssembly();
    
    string targetStr = null;
    if (Device.RuntimePlatform == Device.iOS)
    {
        targetStr = "iOS";
    }
    else if (Device.RuntimePlatform == Device.Android)
    {
        targetStr = "Droid";
    }
    else
    {
        targetStr = "UWP";
    }
    
    using (var stream = assembly.GetManifestResourceStream("App3." + targetStr + ".charm.png"))
    {
        byte[] buffer = new byte[stream.Length];
        stream.Read(buffer, 0, buffer.Length);
        File.WriteAllBytes(filePath, buffer);
    }
    

    The file's build action should be Embedded resource, and use the code below to check what resources you could use in current assembly:
    assembly.GetManifestResourceNames();

  • SreeeeSreeee INMember ✭✭✭✭✭
    edited January 2019

    @LandLu said:
    @Sreeee I think this thread should be closed. If you want to know more information about converting PCL to .NET Standard, you could open a new case. Describe the detailed errors you are facing.
    Then we can find an appropriate workaround there.

    I am also trying to do the same. I tried like below, but still getting FileNotFoundException. I added that picture in my windows project directory.

            var myStr = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
            var filePath = Path.Combine(myStr, "testpic.jpg");
            var fileBytes = File.ReadAllBytes(filePath);
    
  • LandLuLandLu Member, Xamarin Team Xamurai

    @Sreeee Before you read this file in that path, try to print the filePath in the console window. Make sure this file is truely existed:
    File.Exists(filePath);

  • NMackayNMackay GBInsider, University mod

    @Sreeee said:
    @LandLu, @NMackay @ClintStLaurent

    Please suggest the best way of converting PCL to .Net Standard?

    Google the answer
    https://montemagno.com/how-to-convert-a-pcl-library-to-net-standard-and-keep-git-history/

  • SreeeeSreeee INMember ✭✭✭✭✭

    @LandLu, @NMackay @ClintStLaurent

    I am facing an issue when converting PCL project to .Net standard project. Anyone please help me? Started a new thread here.

Sign In or Register to comment.