Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net Bitmap.Clone刚刚抛出;“内存不足”;错误。还有其他选择吗?_.net_Vb.net_Bitmap_Out Of Memory_System.drawing - Fatal编程技术网

.net Bitmap.Clone刚刚抛出;“内存不足”;错误。还有其他选择吗?

.net Bitmap.Clone刚刚抛出;“内存不足”;错误。还有其他选择吗?,.net,vb.net,bitmap,out-of-memory,system.drawing,.net,Vb.net,Bitmap,Out Of Memory,System.drawing,我需要转换一个绘图。位图到4位灰度。有没有办法做到这一点?我尝试过使用Bitmap.Clone,但我只得到了通常臭名昭著的“内存不足”异常。即使它成功地转换为4位,它也是灰度的吗 任何提示都将不胜感激 谢谢 Nelson H没有4bpp灰度图像格式。其次是4bppIndexed,调色板包含16种灰色。GDI+对这种格式的支持非常差,设置像素的唯一方法是直接用Bitmap.LockBits()写入像素。在VB.NET中很难做到这一点,C#更倾向于使用指针操作位图数据。像这样: public

我需要转换一个绘图。位图到4位灰度。有没有办法做到这一点?我尝试过使用Bitmap.Clone,但我只得到了通常臭名昭著的“内存不足”异常。即使它成功地转换为4位,它也是灰度的吗

任何提示都将不胜感激

谢谢


Nelson H

没有4bpp灰度图像格式。其次是4bppIndexed,调色板包含16种灰色。GDI+对这种格式的支持非常差,设置像素的唯一方法是直接用Bitmap.LockBits()写入像素。在VB.NET中很难做到这一点,C#更倾向于使用指针操作位图数据。像这样:

    public unsafe static void Save4bppGrayscale(Bitmap src, string path) {
        var bmp = new Bitmap(src.Width, src.Height, System.Drawing.Imaging.PixelFormat.Format4bppIndexed);

        // Create gray-scale palette
        var pal = bmp.Palette;
        for (int ix = 0; ix < 16; ++ix) {
            var c = 255 * ix / 15;
            pal.Entries[ix] = Color.FromArgb(c, c, c);
        }
        bmp.Palette = pal;

        // Map pixels
        var data = bmp.LockBits(new Rectangle(0, 0, src.Width, src.Height), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format4bppIndexed);
        for (int y = 0; y < src.Height; ++y) {
            byte* line = (byte*)(IntPtr)((long)data.Scan0 + y * data.Stride);
            for (int x = 0; x < src.Width; ++x) {
                var pix = src.GetPixel(x, y);
                var c = (int)(15 * pix.GetBrightness());
                if (x % 2 == 1) c <<= 4;
                *(line + x / 2) |= (byte)c;
            }
        }
        bmp.UnlockBits(data);

        bmp.Save(path, System.Drawing.Imaging.ImageFormat.Bmp);
    }
public不安全静态void Save4bppGrayscale(位图src,字符串路径){
var bmp=新位图(src.Width、src.Height、System.Drawing.Imaging.PixelFormat.Format4bppIndexed);
//创建灰度调色板
var pal=bmp.palete;
对于(int-ix=0;ix<16;++ix){
变量c=255*ix/15;
pal.Entries[ix]=Color.FromArgb(c,c,c);
}
bmp.palete=pal;
//地图像素
var data=bmp.LockBits(新矩形(0,0,src.Width,src.Height),System.Drawing.ImageLockMode.WriteOnly,System.Drawing.Imaging.PixelFormat.Format4bppIndexed);
对于(int y=0;y如果(x%2==1)c如果您试图在ASP.NET网站上完成图像处理,则会发生内存不足异常,因为IIS应用程序池限制了分配的内存量。因此,我们创建了一个独立于IIS的windows服务,并进行转换。在IIS网站中,我们仅以WCF或nam的形式触发该服务ed pipes.

假设
在代码文件顶部导入System.Runtime.InteropServices、System.Drawing.Imaging
(锁位并不难,我用它做了很多图像处理,更喜欢VB.NET而不是C#)


当然,这种方法并不快(对于我来说,800万像素的图像大约需要1-2秒)但这也不错。

这会有帮助吗?:对你来说速度非常慢的一个原因是,你使用GetPixel,而不是从指针上读和写。是的,根据需要进行改进和润色。问题海报没有提到任何关于ASP.NET的内容;反正这不是他的问题。另外,我在ASP.NET中做过图像处理,没有经验取消任何此类异常。您能进一步解释一下此代码吗?更具体地说,如何调整代码以实现“无论什么”的结果?我正在寻找创建1bpp图像。要实现这一点,我需要做哪些更改?
Private Sub To4BitGrayScale(ByVal b As Bitmap)
    Dim bd As BitmapData = b.LockBits(New Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, ImageFormat.Format24BppRgb)
    Dim arr(bd.Width * bd.Height * 3 - 1) As Byte
    Marshal.Copy(bd.Scan0, arr, 0, arr.Length)

    For i As Integer = 0 To arr.Length - 1 Step 3
        Dim c As Color = Color.FromArgb(255, arr(i), arr(i + 1), arr(i + 2))

        ' Convert c to grayscale however you want; weighted, average, whatever.

        arr(i) = c.R
        arr(i + 1) = c.G
        arr(i + 2) = c.B
    Next

    Marshal.Copy(arr, 0, bd.Scan0, arr.Length)
    b.UnlockBits(bd)
End Sub