Загрузка больших изображений на FTP останавливает приложение - PullRequest
1 голос
/ 02 апреля 2019

Я пытаюсь загрузить некоторые изображения на свой FTP в форме.Он отлично работает на моем Huawei P20, но мне сообщили, что на телефоне с меньшим объемом ОЗУ приложение зависает при попытке загрузить большие изображения.

После выбора изображения (максимум 4) Я изменяю размеры изображений и сжимаю их, чтобы уменьшить размер, но безуспешно

Код:

   public static byte[] RotateImage(string path)
        {
            byte[] imageBytes;

            var originalImage = BitmapFactory.DecodeFile(path);
            var rotation = GetRotation(path);
            //Width 3000 Height 4000

            var width = (originalImage.Width * 0.25);
            var height = (originalImage.Height * 0.25);
            if(originalImage.Height>2400)
            {
               width = (originalImage.Width * 0.20);
               height = (originalImage.Height * 0.20);
            }
            if (originalImage.Height < 600)
            {
                width = (originalImage.Width * 0.80);
                height = (originalImage.Height * 0.80);
            }

            var scaledImage = Bitmap.CreateScaledBitmap(originalImage, (int)width, (int)height, true);

            Bitmap rotatedImage = scaledImage;
            if (rotation != 0)
            {
                var matrix = new Matrix();
                matrix.PostRotate(rotation);

                rotatedImage = Bitmap.CreateBitmap(scaledImage, 0, 0, scaledImage.Width, scaledImage.Height, matrix, true);
                scaledImage.Recycle();
                scaledImage.Dispose();
            }

            using (var ms = new MemoryStream())
            {
                if (rotatedImage.Width > 1000 || rotatedImage.Height > 1000)
                {
                    rotatedImage.Compress(Bitmap.CompressFormat.Jpeg, 30, ms);
                }

                if (rotatedImage.Width < 500 || rotatedImage.Height < 500)
                {
                    rotatedImage.Compress(Bitmap.CompressFormat.Jpeg, 60, ms);
                }

                if (rotatedImage.Width <= 1000 && rotatedImage.Width >= 500)
                {
                    rotatedImage.Compress(Bitmap.CompressFormat.Jpeg, 45, ms);
                }
                imageBytes = ms.ToArray();
            }

            originalImage.Recycle();
            rotatedImage.Recycle();
            originalImage.Dispose();
            rotatedImage.Dispose();
            GC.Collect();

            return imageBytes;
        }

Затем я отправляю их в MessagingCenter и извлекаю их в PCL.Приложение зависает, когда я пытаюсь загрузить его на FTP

Код в PCL:

    for (int i = 0; i < _images.Count; i++)
                    {

                        DependencyService.Get<IFtpWebRequest>().upload("FTP", _images[i], "SITE", "PASSWORD", "DIRECTORY");

                    }

и код конкретной платформы, которую я вызываю:

 public string upload(string FtpUrl, string fileName, string userName, string password, string UploadDirectory = "")
    {

        try
        {
            WebRequest request = WebRequest.Create(FtpUrl+UploadDirectory);
            request.Method = WebRequestMethods.Ftp.MakeDirectory;
            request.Credentials = new NetworkCredential(userName, password);
            using (var resp = (FtpWebResponse)request.GetResponse())
            {

            }

        }
        catch(Exception e) {  }



        try
        {

            string PureFileName = new FileInfo(fileName).Name;
            String uploadUrl = String.Format("{0}{1}/{2}", FtpUrl, UploadDirectory, PureFileName);

            FtpWebRequest req = (FtpWebRequest)FtpWebRequest.Create(uploadUrl);
            req.Proxy = null;
            req.Method = WebRequestMethods.Ftp.UploadFile;
            req.Credentials = new NetworkCredential(userName, password);
            req.UseBinary = true;
            req.UsePassive = true;
            byte[] data = File.ReadAllBytes(fileName);
            req.ContentLength = data.Length;
            Stream stream = req.GetRequestStream();
            stream.Write(data, 0, data.Length);
            stream.Close();
            FtpWebResponse res = (FtpWebResponse)req.GetResponse();
            return res.StatusDescription;

        }
        catch (Exception err)
        {
            return err.ToString();
        }
    }

ожидаемым результатом должно быть приложение, не зависающее на любом телефоне.Что я мог сделать, чтобы предотвратить это?Дальнейшее увеличение сжатия не является лучшим решением, так как некоторые телефоны загружают его без проблем, и поэтому я могу добиться более высокого качества.

РЕДАКТИРОВАТЬ: при загрузке большого изображения на FTP и я проверяю рис на FTP, как 1/10 изизображение загружено, остальное пусто

EDIT2: перемещение функции в другой поток больше не останавливает приложение, но все же только часть iamge загружается на устройства с меньшим объемом памяти, как мне как-то принудительно заставитьцелое изображение для загрузки?

1 Ответ

0 голосов
/ 03 апреля 2019

При загрузке большого изображения на FTP, и я проверяю изображение на FTP, оно выглядит как 1/10 изображения, остальное пустое

Если загруженное изображение очень большое, то это будет трудоемкая операция.Если он помещен в основной поток пользовательского интерфейса, он будет занимать много памяти и времени.Когда память мобильного телефона велика, возможно, она сможет выполнить задачу, но когда телефон невелик, тогда возникнет проблема.

Вам необходимо перенести метод загрузки в тему backgroud., то это не повлияет на поток пользовательского интерфейса.

Если в Android , попробуйте с Task :

public async Task<string> upload(string FtpUrl, string fileName, string userName, string password, string UploadDirectory = "")
{

  await Task.Run(() =>
  {
        try
        {
            WebRequest request = WebRequest.Create(FtpUrl+UploadDirectory);
            request.Method = WebRequestMethods.Ftp.MakeDirectory;
            request.Credentials = new NetworkCredential(userName, password);
            using (var resp = (FtpWebResponse)request.GetResponse())
            {

            }

        }
        catch(Exception e) {  }

        ...
  });
}
...