Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/265.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
C# 使用而不使用Graphics.DrawImage将一个位图复制到较大的位图上_C#_Graphics_Drawing_Bitmap_Unmanaged - Fatal编程技术网

C# 使用而不使用Graphics.DrawImage将一个位图复制到较大的位图上

C# 使用而不使用Graphics.DrawImage将一个位图复制到较大的位图上,c#,graphics,drawing,bitmap,unmanaged,C#,Graphics,Drawing,Bitmap,Unmanaged,这是来自 我试图实现的是,使用位图锁定位功能或任何其他功能(而不是graphics.DrawImage),在较大图像上的任意点,获取一个50x50像素的位图,并将其绘制到较大的位图(100x100像素)上。我不想使用DrawImage的原因在另一个线程中说明 通过使用Marshal.Copy从源BitmapData复制到目标BitmapData,我成功地获得了一些信息,但这会创建一个平铺的、水平拉伸的图像。我建议您看一下 我认为最好的方法是不要直接设置BitmapData。相反,我将创建一个大小

这是来自

我试图实现的是,使用位图锁定位功能或任何其他功能(而不是graphics.DrawImage),在较大图像上的任意点,获取一个50x50像素的位图,并将其绘制到较大的位图(100x100像素)上。我不想使用DrawImage的原因在另一个线程中说明


通过使用Marshal.Copy从源BitmapData复制到目标BitmapData,我成功地获得了一些信息,但这会创建一个平铺的、水平拉伸的图像。

我建议您看一下

我认为最好的方法是不要直接设置BitmapData。相反,我将创建一个大小合适的单个共享字节数组,并直接从较小的图像设置字节数组

在合成较大的图像时,可以直接从字节数据获取最终的字节数组


它的优点是允许您控制内存管理、线程操作等,就像您在最初的文章中所想的那样。数据访问速度也应该非常快。

我建议您看看

我认为最好的方法是不要直接设置BitmapData。相反,我将创建一个大小合适的单个共享字节数组,并直接从较小的图像设置字节数组

在合成较大的图像时,可以直接从字节数据获取最终的字节数组


它的优点是允许您控制内存管理、线程操作等,就像您在最初的文章中所想的那样。数据访问速度也应该非常快。

您可以在内存中操作映像,而无需依赖任何系统调用。如果深入研究.BMP文件的底层格式,您可以构建自己的独立于设备的位图类,该类真正“理解”了.BMP的底层格式

例如,每像素8位的图像本质上是一个字节的二维数组(每个字节是1个像素)加上一个简单的颜色表。粗略地说(这是非常非常粗略的):

诀窍是(一如既往)获取原始像素数据,进行处理,然后用更改更新原始像素数据

在过去,我通过将GDI HBITMAP转换为24bpp的DIB来实现这一点,在原始像素上执行我的时髦图像处理(每像素3字节使这更容易),然后将DIB转换回HBITMAP。这一切都只使用了经典的GDI(GDI+之前的偶数,更不用说C了)

使用这种方法,您可以设计一个控制结构,允许多个作者访问更大图像的不同部分

然而。。。低级别的BitBlt-GDI调用可能比您所能做的任何事情都更有效率。如果我是你,我会确保仅仅连续做50或100位BLT太慢(你可能需要用c++来做)

处理DIB的最烦人挑战是:

  • 将DIB转换为实际“图像”,以便显示和
  • 将实际“图像”转换为DIB
  • 将DIB另存为.BMP以外的内容
  • 当我开始学习图像实际上是“恐怖”时的核心参考:


    如何访问.NET映像的。。。好。。。这是一个很好的问题:)

    您可以在内存中操作映像,而无需依赖任何系统调用。如果深入研究.BMP文件的底层格式,您可以构建自己的独立于设备的位图类,该类真正“理解”了.BMP的底层格式

    例如,每像素8位的图像本质上是一个字节的二维数组(每个字节是1个像素)加上一个简单的颜色表。粗略地说(这是非常非常粗略的):

    诀窍是(一如既往)获取原始像素数据,进行处理,然后用更改更新原始像素数据

    在过去,我通过将GDI HBITMAP转换为24bpp的DIB来实现这一点,在原始像素上执行我的时髦图像处理(每像素3字节使这更容易),然后将DIB转换回HBITMAP。这一切都只使用了经典的GDI(GDI+之前的偶数,更不用说C了)

    使用这种方法,您可以设计一个控制结构,允许多个作者访问更大图像的不同部分

    然而。。。低级别的BitBlt-GDI调用可能比您所能做的任何事情都更有效率。如果我是你,我会确保仅仅连续做50或100位BLT太慢(你可能需要用c++来做)

    处理DIB的最烦人挑战是:

  • 将DIB转换为实际“图像”,以便显示和
  • 将实际“图像”转换为DIB
  • 将DIB另存为.BMP以外的内容
  • 当我开始学习图像实际上是“恐怖”时的核心参考:


    如何访问.NET映像的。。。好。。。这是一个很好的问题:)

    如果您使用的是32bpp[p]ARGB像素格式,那么使用LockBits/BitmapData应该可以很好地工作。诀窍是,您必须一次复制一行数据,以便它在正确的位置对齐。您应该能够使用以下方法完成此操作:

    Rectangle srcArea = new Rectangle(0, 0, srcBitmap.Width, srcBitmap.Height);
    BitmapData srcData = srcBitmap.LockBits(srcArea, ImageLockMode.ReadOnly, destBitmap.PixelFormat);
    Rectangle destArea = new Rectangle(25, 25, srcBitmap.Width, srcBitmap.Height);
    BitmapData destData = destBitmap.LockBits(destArea, ImageLockMode.WriteOnly, destBitmap.PixelFormat);
    
    IntPtr srcPtr = srcData.Scan0;
    IntPtr destPtr = destData.Scan0;
    byte[] buffer = new byte[srcData.Stride];
    for (int i = 0; i < srcData.Height; ++i)
    {
        Marshal.Copy(srcPtr, buffer, 0, buffer.Length);
        Marshal.Copy(buffer, 0, destPtr, buffer.Length);
    
        srcPtr += srcData.Stride;
        destPtr += destData.Stride;
    }
    
    srcBitmap.UnlockBits(srcData);
    destBitmap.UnlockBits(destData);
    
    Rectangle srcArea=新矩形(0,0,srcbimpet.Width,srcbimpet.Height);
    BitmapData srcData=srcBitmap.LockBits(srcArea、ImageLockMode.ReadOnly、destBitmap.PixelFormat);
    矩形destArea=新矩形(25,25,srcBitmap.Width,srcBitmap.Height);
    BitmapData destData=destBitmap.LockBits(destArea,ImageLockMode.WriteOnly,destBitmap.PixelFormat);
    IntPtr srcPtr=srcData.Scan0;
    IntPtr destPtr=destData.Scan0;
    字节[]缓冲区=新字节[srcData.Stride];
    对于(int i=0;iRectangle srcArea = new Rectangle(0, 0, srcBitmap.Width, srcBitmap.Height);
    BitmapData srcData = srcBitmap.LockBits(srcArea, ImageLockMode.ReadOnly, destBitmap.PixelFormat);
    Rectangle destArea = new Rectangle(25, 25, srcBitmap.Width, srcBitmap.Height);
    BitmapData destData = destBitmap.LockBits(destArea, ImageLockMode.WriteOnly, destBitmap.PixelFormat);
    
    IntPtr srcPtr = srcData.Scan0;
    IntPtr destPtr = destData.Scan0;
    byte[] buffer = new byte[srcData.Stride];
    for (int i = 0; i < srcData.Height; ++i)
    {
        Marshal.Copy(srcPtr, buffer, 0, buffer.Length);
        Marshal.Copy(buffer, 0, destPtr, buffer.Length);
    
        srcPtr += srcData.Stride;
        destPtr += destData.Stride;
    }
    
    srcBitmap.UnlockBits(srcData);
    destBitmap.UnlockBits(destData);