内存不足,读取3Gb Ram的大图像(超过300Mb) [英] Out of Memory reading big images (more than 300Mb) with 3Gb of Ram

查看:97
本文介绍了内存不足,读取3Gb Ram的大图像(超过300Mb)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您好,我想知道如何打开和修改大图片文件,我需要替换一些像素的颜色,但是当我尝试打开大文件(它们是来自地图的图像,并且大小为300 Mb或更大)时,我收到内存不足"错误.

我的代码是:

Hi, I would like know, how open and modify big picture files, I need replace color in some pixels but when I try to open big files (they are images from maps, and the size is 300 or more Mb), I get a "out of memory" error.

My code is:

Private Sub BMW_Filtrar_DoWork(ByVal sender As System.Object, _
                                   ByVal e As System.ComponentModel.DoWorkEventArgs) _
                                   Handles BMW_Filtrar.DoWork
        Dim Archivo_Local As FileInfo = CType(e.Argument, FileInfo)
        If Archivo_Local.Exists = False Then Exit Sub

        Dim FSB As System.IO.FileStream
        FSB = New FileStream(Archivo_Local.FullName, FileMode.Open, FileAccess.Read)
        Dim L_Bitmap As Bitmap = Image.FromStream(FSB)
        Dim i, j, Cont1, Cont2, Cont3, Cont4 As Integer
        Dim Color_Px As System.Drawing.Color

        ''--- BUSCAR FILAS EN BLANCO PARTE SUPERIOR E INFERIOR ---
        Dim Flag1 = False, Flag2 As Boolean = False
        For i = 0 To L_Bitmap.Height - 1 Step 1
            ''COL CYCLE
            For j = 0 To L_Bitmap.Width - 1 Step 1


                Color_Px = L_Bitmap.GetPixel(j, i)
''REPLACE COLOR PIXEL
                With Color_Px
                    If .R >= 128 Or .G > 180 Then L_Bitmap.SetPixel(j, i, Color.White)
                    If .G <= 130 And .B <= 100 Then L_Bitmap.SetPixel(j, i, Color.White)
                End With

            Next ''FIN CICLO COLUMNAS
        Next

        L_Bitmap.Save(Archivo_Local.Directory.FullName & "\Archivo.tif")
Salir:
        Try
            L_Bitmap.Dispose()
            L_Bitmap = Nothing
            FSB.Close()
        Catch ex As Exception

        End Try
    End Sub



在此先感谢您的帮助.

最好的问候,

Freddy Coal



Thanks in advance for any help.

My best regards,

Freddy Coal

推荐答案

磁盘上的文件大小可能为300MB,但内存中的Bitmap对象可能更大,具体取决于图像的大小和颜色深度.

您没有提到此大小是多少,因此无法确定.
The on-disk file size may be 300MB, but the Bitmap object in memory may be much larger, depending on the dimensions of the image and the color depth.

You don''t mention what this size is, so it''s impossible to say for sure.


您是否已在调试器下运行代码?顺便说一句,为了最佳实践",我会在所有代码中放置try/catch块.
have you run your code under the debugger? BTW, I''d put the try/catch block around all your code in the interest of "best practice".


尽管有最大的印象,我会尽力提供帮助在我的机器上是2800x1400 .jpg(2mb).我对.tif图像工作不多,也从未处理过映射中使用的图像.但是,您可以尝试一些操作(如果尚未使用)来处理较大图像中的块.

首先,将您的工作图像与原始图像分开.为此,请创建一个与磁盘映像具有相同物理尺寸的空位图.从该空白图像创建图形对象.接下来,从磁盘加载原始文件并将其绘制在先前创建的图形对象中.然后处置刚刚加载的原件的副本,以使程序与磁盘映像之间没有链接.

从您刚创建的图像(称为工作图像"),从工作图像的矩形部分创建另一个图像.这将是您希望以某种方式处理的块.在此新图像上执行所需的更改,然后将其绘制回工作图像(再次使用图形对象).

完成所有所需的更改后,您可以覆盖原始文件或将其写到新文件中.下面的代码演示了获取原始副本,然后从该副本中获取块选择的步骤.进行更改后,可以使用类似的过程将块写回到工作映像,然后再将工作映像写回到磁盘.您不应该以这种方式遇到任何内存错误.

I''ll try to help with this, although the biggest image on my machine is a 2800x1400 .jpg (2mb). I''ve not worked much with .tif images and have never worked with images used in mapping. There are however a few things you can try (if you haven''t already) to work with blocks from a larger image.

First, isolate your working image from the original. To do this, create an empty bitmap of the same physical dimensions as the disk image. Create a graphics object from that empty image. Next, load the original from disk and draw it in the previously-created graphics object. Then dispose of the copy of the original you just loaded, so there is no link between your program and the disk image.

From the image you''ve just created (call it the "working image"), create yet another image from a rectangular section of the working image. This would be the block you wish to process in some way. Perform the desired changes on this new image, and then draw it back to the working image (using the graphics object again).

Once all desired changes are made, you can then overwrite the original or write it out to a new file. The code below demonstrates the steps to get the copy of the original and then get a block selection from that copy. Once you''ve made your changes, you can use a similar process to write the block back to your working image, and then write the working image back to disk. You shouldn''t run into any memory errors this way.

'get original image
Dim original As Bitmap = Bitmap.FromFile("bigimage.tif")

'create working image
Dim workingImage As New Bitmap(original.Width, original.Height)
Dim g As Graphics = Graphics.FromImage(workingImage)
g.DrawImage(original, 0, 0, original.Width, original.Height)

'dump the original
original.Dispose()

'now get the block to process
'this assumes you want to process a 300x300 area of the original
Dim block As New Bitmap(300, 300)

'this rectangle assumes you wish to grab a 300x300 section
'of the original, starting at point 100x100
Dim selRect As New Rectangle(100, 100, 300, 300)

'this rect represents the dimensions of your block image
'and the coords where you'll draw from the working image
Dim drawRect As New Rectangle(0, 0, 300, 300)

'now get the block
Dim blockGraphics As Graphics = Graphics.FromImage(block)
blockGraphics.DrawImage(workingImage, drawRect, selRect, GraphicsUnit.Pixel)


'your code to process the image goes here
'
'

'then use a similar code block to write the
'block image back to the working image
'lastly, write the working image to disk.


这篇关于内存不足,读取3Gb Ram的大图像(超过300Mb)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆