ephrem33 Ответов: 4

Image.fromfile() выбрасывает исключение из памяти


Я пытаюсь отобразить изображение .tif размером 136 МБ. Но Образ.FromFile(...) продолжает выбрасывать исключение из памяти я вручную увеличил размер виртуальной памяти примерно до 4 ГБ, но безрезультатно.

Я проверил файл изображения, чтобы убедиться, что он не поврежден, и я могу видеть изображение через другие редакторы, которые поставляются с моей операционной системой.
Моя операционная система-Windows-XP Service pack 3, и я использую Visual Studio 2008.

Что я уже пробовал:

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

Я знаю, что этот код не совсем делает то, что он обещает, но я должен начать с разрешения исключения из памяти.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;
using System.IO;
using System.Threading;



namespace 2DSatelliteMap
{
    public partial class Form1 : Form
    {
        private Thread ImageLoaderThread;
        Image Addis;
        private float xScale = 1.0f;
        private float yScale = 1.0f;
        private Point[] AddisBounds;
        bool isImageLoaded = false;
        int panelWidth;
        int panelHeight;
        double WidthPixelNumber = 1;
        double HeightPixelNumber = 1;

        public Form1()
        {
            InitializeComponent();
            this.AutoScroll = true;
            panel1.AutoScroll = true;
            panelWidth = panel1.Width;
            panelHeight = panel1.Height;
            this.panel1.MouseMove += new System.Windows.Forms.MouseEventHandler(this.panel1_MouseMove);
        }

        private void panel1_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            // Update the mouse position that is displayed in the text boxes.
            if (isImageLoaded)
            {
                //txtEasting.Text = e.X.ToString();
                txtEasting.Text = CalculateEasting(e.X).ToString();
                txtNorthing.Text = CalculateNorthing(e.Y).ToString();
               // txtNorthing.Text = e.Y.ToString();
            }
        }

        delegate void SetTextCallback(string text);

        private void SetTextEasting(string text)
        {
            if (this.txtLatitude.InvokeRequired)
            {
                SetTextCallback d = new SetTextCallback(SetTextEasting);
                this.Invoke(d, new object[] { text });
            }
            else
            {
                this.txtLatitude.Text = text;
            }
        }

        private void SetTextNorthing(string text)
        {
            if (this.txtLongitude.InvokeRequired)
            {
                SetTextCallback d = new SetTextCallback(SetTextNorthing);
                this.Invoke(d, new object[] { text });
            }
            else
            {
                this.txtLongitude.Text = text;
            }
        }

        private double CalculateEasting(int coordinate)
        {
            if (Addis != null)
            {
                WidthPixelNumber = (Addis.Width * coordinate) / panelWidth;
            }
            return (471999.59999999998000000 + 0.60000000000000175 * WidthPixelNumber);
        }

        private double CalculateNorthing(int coordinate)
        {
            if (Addis != null)
            {
                HeightPixelNumber = (Addis.Height * coordinate) / panelHeight;
            }
            return (991447.80000000005000000 + -0.59999999999999620 * HeightPixelNumber);
        }        

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            Graphics dc = panel1.CreateGraphics();
            dc.ScaleTransform(xScale, yScale);

            if (Addis != null)
            {
                dc.DrawImage(Addis, AddisBounds); // TODO: throws Out of Memory exception
               // dc.Dispose();
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void btnLoadMap_Click(object sender, EventArgs e)
        {
            openFileDialog.Filter = "All image files |*.tif";
            openFileDialog.ShowDialog();
            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                string fileName = openFileDialog.FileName;
                ImageLoaderThread = new Thread(new ParameterizedThreadStart(LoadImage));
                ImageLoaderThread.Start(fileName);
            }
        }

        private void LoadImage(object obj)
        {
            string filePath = (string)obj;
            try
            {
                Addis = Image.FromFile(filePath);
                isImageLoaded = true;
            }

            catch (Exception ex)
            {
                MessageBox.Show("Error in loading image...");
            }

            AddisBounds = new Point[3];
            AddisBounds[0] = new Point(0, 0);
            AddisBounds[1] = new Point(panel1.Right, 0);
            AddisBounds[2] = new Point(0, panel1.Bottom - panel1.Top);

            SetTextEasting("Width" + Addis.Width.ToString());
            SetTextNorthing("Height" + Addis.Height.ToString());

            Invalidate();
        }

        private void btnZoonIn_Click(object sender, EventArgs e)
        {
            xScale += 0.5f;
            yScale += 0.5f;
            Invalidate();
            txtLatitude.Text = Addis.Size.ToString();
        }

        private void btnZoomOut_Click(object sender, EventArgs e)
        {

            if (xScale > 1.0)
            {
                xScale -= 0.5f;
                yScale -= 0.5f;
            }
            Invalidate();
        }

        private void btnFitMap_Click(object sender, EventArgs e)
        {
            xScale = 1.0f;
            yScale = 1.0f;
            Invalidate();
        }

        private void panel1_Paint_1(object sender, PaintEventArgs e)
        {
        }

        private void txtEasting_TextChanged(object sender, EventArgs e)
        {

        }
    }
}

4 Ответов

Рейтинг:
30

OriginalGriff

Я никогда не пробовал 136MB TIF, но я имел дело с BMP и JPG файлами, которые намного больше, чем это без проблем. Отредактируйте существующий код и покажите нам метод, в котором происходит исключение - заключите его в виджет "блок кода", чтобы сохранить форматирование.


Рейтинг:
22

Sandeep Mewara

Ефремов писал::
a .tif-изображение размером 136 МБ


Это очень большой вопрос! Я бы посоветовал вам трансформироваться в более светлый тип изображения, а затем попытаться использовать его.

Кроме того, большие изображения, подобные этим, было бы трудно сохранить и восстановить.
В противном случае, взгляните на эту тему, звучит аналогично с предложенным разрешением: Черно-белое (формат TIFF) преобразователь изображения для .Чистая[^]


Рейтинг:
2

Rahman Roohi

Вы не можете использовать изображение.FromStream для вашего файла, вместо этого вы должны декодировать файл с помощью TiffBitmapDecoder. Пример кода из MSDN:

// Open a Stream and decode a TIFF image
Stream imageStreamSource = new FileStream("tulipfarm.tif", FileMode.Open, FileAccess.Read, FileShare.Read);
TiffBitmapDecoder decoder = new TiffBitmapDecoder(imageStreamSource, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
            BitmapSource bitmapSource = decoder.Frames[0];
            
// Draw the Image
Image myImage = new Image();
myImage.Source = bitmapSource;
myImage.Stretch = Stretch.None;
myImage.Margin = new Thickness(20);


Member 4327886

Я хочу, чтобы преобразовать файл TIFF в JPEG в vb.net. У меня возникла проблема, когда я открываю файл TIFF. Я открыл файл Tiff тремя способами. Это объясняется ниже..

Пункт № 1 :
Изображение.FromFile(..image path...) - это дает ошибку Out of memory
Image.stream(...image path..)- неверный параметр

-- Объем одного файла превышает 70 МБ.
Как я могу получить решение с помощью dot net framework?
Я не хочу делать внешний OCX.

Пожалуйста, уговорите меня...????
Заранее спасибо...

Рейтинг:
16

Ryan McBeth

Я согласен с Сандипом.

Однажды я написал драйвер камеры для Windows CE. Большая часть моего опыта работы с изображениями исходит из Windows CE / Mobile, поэтому я не могу полностью говорить о том, что именно происходит в Win32, но я бы предположил, что есть сходство.

Это изображение действительно загружается дважды и преобразуется в растровое изображение для отображения на экране. Так что на самом деле вам нужно удвоить объем своей памяти. Я обошел это, создавая предварительный просмотр изображения каждый раз, когда я захватил полное изображение. Я бы показывал предварительный просмотр, пока обрабатывается реальное изображение. Если пользователь хотел увеличить масштаб, я загружал полное изображение. Большинство пользователей приняли быстрое решение о том, Сохранить изображение или отказаться от него менее чем за секунду, поэтому этот предварительный просмотр сэкономил много времени на обработку.

Или, как сказал Сандип, создайте эскиз этого изображения и отобразите его, если ваше приложение может справиться с этим.

Я не вижу много приложений, где вам нужно подлинное изображение с высоким разрешением, если только вы не разрабатываете профессиональное программное обеспечение для фотографий (что вы не обязательно будете делать в .NET) или не делаете какую-то медицинскую или промышленную визуализацию, где вам нужно увеличить масштаб или трещины в кости или поры в бетоне моста. И даже в этом случае вы можете разделить это изображение на сектора, которые вы можете загрузить по мере необходимости.

Вы определенно привязаны к большому файлу из-за приложения?

Райан Макбет