Click here to Skip to main content
15,884,627 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I am trying to display a .tif image of 136MB size. But Image.FromFile(...) keeps on throwing out of memory exception I manually increased the size of the virtual memory to around 4GB but to no avail.

I have checked image file to make sure that it is not corrupted and I can see the image through other editors that come with my operating system.
My operating system is Windows-XP Service pack 3 and I am using Visual Studio 2008.

What I have tried:

As you can see from my code, I am trying to load a .tiff file to a Panel. I need that much big file because the map will have a zoom in/out functionality.

I know this code doesn't exactly do what it promises but I have to start by resolving the out of memory exception.

C#
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)
        {

        }
    }
}
Posted
Updated 30-Aug-19 9:25am
v2

I've never tried a 136MB TIF, but I have dealt with BMP and JPG files that are much larger than that without problems. Edit your existing code, and show us the method that the exception is occurring in - enclose it with the "code block" widget to preserve the formatting.
 
Share this answer
 
ephrem33 wrote:
a .tif image of 136MB size


Thats a big one! I would suggest you to transform into lighter image type and then try to use it.

Further, large images like these would be difficult to save and retrieve.
Otherwise, have a look at this thread, sounds similar thing with suggested resolution: Bitonal (TIFF) Image Converter for .NET[^]
 
Share this answer
 
I agree with Sandeep.

I wrote a camera driver for Windows CE once. Most of my experience with images comes from Windows CE / Mobile, so I can't fully speak for exactly what is going on in Win32, but I would assume that there are similarities.

That image is really getting loaded twice and being converted to a bitmap for display on screen. So in reality, you need to double your memory size. I got around this by creating a preview image every time I captured the full image. I would display the preview while the real image processed. If the user wanted to zoom, I loaded the full image. Most users made a quick decision as to whether to keep the image or discard in less than a second, so this preview saved a lot of processing time.

Or, like Sandeep said, create a thumbnail of that image and display that, if your application can handle that.

I can't see many applications where you need a genuine high-resolution image, unless you are developing professional photo software (which you wouldn't necessarily be doing in .NET) or doing some kind of medical or industrial imaging where you need to zoom in or the cracks in a bone or the pores in a bridge's concrete. And even in that case, you can split that image up into sectors that you can load as needed.

Are you definitely tied to a large file because of the application?

Ryan McBeth
 
Share this answer
 
You can't use Image.FromStream for your file, instead you must decode the file using TiffBitmapDecoder. Sample code from MSDN:
C#
// 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);
 
Share this answer
 
v2
Comments
Member 4327886 6-Sep-12 23:19pm    
I want to convert the Tiff file to JPEG in vb.net. I got the problem when i am opening the TIFF file. I have opened the Tiff file in 3 ways. That is explained below..

Point No 1 :
Image.FromFile(..image path...) - It is giving the Out of memory error
Image.stream(...image path..)- incorrect parameter

-- The single file volume is greater than 70 MB.
How can i get the solution using dot net framework.
I dont want to do external OCX.

Please suguest me....????
Thanks in advance...

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900