C# 从SharpDX位图转换为GorgonImage失败
我在项目中使用2D库(基于SharpDX构建)。我在从SharpDX位图转换到GorgonImage时遇到问题。我把我的问题贴在这里,希望你们能帮我解决。谢谢 我使用以下代码创建SharpDX位图:C# 从SharpDX位图转换为GorgonImage失败,c#,sharpdx,C#,Sharpdx,我在项目中使用2D库(基于SharpDX构建)。我在从SharpDX位图转换到GorgonImage时遇到问题。我把我的问题贴在这里,希望你们能帮我解决。谢谢 我使用以下代码创建SharpDX位图: private GorgonImage D2DBitmapToGorgonImage(this SharpDX.Direct2D1.Bitmap1 bm, SharpDX.Direct2D1.DeviceContext5 D2D1Context5) { SharpDX.DataRectang
private GorgonImage D2DBitmapToGorgonImage(this SharpDX.Direct2D1.Bitmap1 bm, SharpDX.Direct2D1.DeviceContext5 D2D1Context5)
{
SharpDX.DataRectangle map;
if (bm.Options == SharpDX.Direct2D1.BitmapOptions.Target)
{
var img1 = new SharpDX.Direct2D1.Bitmap1(D2D1Context5, new SharpDX.Size2(bm.PixelSize.Width, bm.PixelSize.Height), new SharpDX.Direct2D1.BitmapProperties1()
{
PixelFormat = new SharpDX.Direct2D1.PixelFormat(DXGI.Format.R8G8B8A8_UNorm, SharpDX.Direct2D1.AlphaMode.Premultiplied),
DpiX = 96,
DpiY = 96,
BitmapOptions = SharpDX.Direct2D1.BitmapOptions.CannotDraw | SharpDX.Direct2D1.BitmapOptions.CpuRead
});
img1.CopyFromBitmap(bm, new SharpDX.Mathematics.Interop.RawPoint(0, 0), new SharpDX.Mathematics.Interop.RawRectangle(0, 0, bm.PixelSize.Width, bm.PixelSize.Height));
map = img1.Map(SharpDX.Direct2D1.MapOptions.Read);
img1.Unmap();
img1.Dispose();
}
else if (bm.Options == (SharpDX.Direct2D1.BitmapOptions.CannotDraw | SharpDX.Direct2D1.BitmapOptions.CpuRead))
map = bm.Map(SharpDX.Direct2D1.MapOptions.Read);
else
throw new Exception("Can not convert from Direc2D1.Bitmap1 to GorgonImage");
var size = bm.PixelSize.Width * bm.PixelSize.Height * 4;
byte[] bytes = new byte[size];
Marshal.Copy(map.DataPointer, bytes, 0, size);
IGorgonImageInfo info = new GorgonImageInfo(ImageType.Image2D, BufferFormat.R8G8B8A8_UNorm)
{
Width = bm.PixelSize.Width,
Height = bm.PixelSize.Height,
};
GorgonImage nqi = new GorgonImage(info);
unsafe
{
for (int y = 0; y < info.Height; y++)
{
// We only need the width here, as our pointer will handle the stride by virtue of being an int.
//int* offset = pixels + (y * bitmapLock.Width);
int destOffset = y * nqi.Buffers[0].PitchInformation.RowPitch;
for (int x = 0; x < info.Width; x++)
{
var position = (y * info.Width + x) * 4;
byte r = 0, g = 0, b = 0, alpha = bytes[position + 3];
if(bm.PixelFormat.AlphaMode == SharpDX.Direct2D1.AlphaMode.Premultiplied)
{
if (alpha != 0)
{
var div_alpha = 0xff00 / alpha;
r = (byte)((bytes[position] * div_alpha + 0x80) >> 8);
g = (byte)((bytes[position + 1] * div_alpha + 0x80) >> 8);
b = (byte)((bytes[position + 2] * div_alpha + 0x80) >> 8);
}
}
else
{
r = bytes[position+1];
g = bytes[position+2];
b = bytes[position+3];
}
SharpDX.Color4 cl4 = new SharpDX.Color4((float)r/255.0f, (float)g/255.0f, (float)b/255.0f, (float)alpha/255.0f);
// The DXGI format nomenclature is a little confusing as we tend to think of the layout as being highest to
// lowest, but in fact, it is lowest to highest.
// So, we must convert to ABGR even though the DXGI format is RGBA. The memory layout is from lowest
// (R at byte 0) to the highest byte (A at byte 3).
// Thus, R is the lowest byte, and A is the highest: A(24), B(16), G(8), R(0).
int* destBuffer = (int*)(Unsafe.AsPointer(ref nqi.Buffers[0].Data[destOffset]));
*destBuffer = cl4.ToRgba(); //color.ToABGR();
//offset++;
destOffset += 4;
}
}
}
return nqi;
}
private GorgonImage D2DBitmapToGorgonImage(此SharpDX.Direct2D1.Bitmap1 bm、SharpDX.Direct2D1.DeviceContext5 d1Context5)
{
SharpDX.DataRectangle映射;
if(bm.Options==SharpDX.Direct2D1.BitmapOptions.Target)
{
var img1=new SharpDX.Direct2D1.Bitmap1(D2D1Context5,new SharpDX.Size2(bm.PixelSize.Width,bm.PixelSize.Height),new SharpDX.Direct2D1.BitmapProperties1()
{
PixelFormat=新的SharpDX.Direct2D1.PixelFormat(DXGI.Format.R8G8B8A8_UNorm,SharpDX.Direct2D1.AlphaMode.Premultiplied),
DpiX=96,
DpiY=96,
BitmapOptions=SharpDX.Direct2D1.BitmapOptions.CannotDraw | SharpDX.Direct2D1.BitmapOptions.CpuRead
});
img1.CopyFromBitmap(bm,新的SharpDX.Mathematics.Interop.RawPoint(0,0),新的SharpDX.Mathematics.Interop.RawRectangle(0,0,bm.PixelSize.Width,bm.PixelSize.Height));
map=img1.map(SharpDX.Direct2D1.MapOptions.Read);
img1.Unmap();
img1.Dispose();
}
else if(bm.Options==(SharpDX.Direct2D1.BitmapOptions.CannotDraw | SharpDX.Direct2D1.BitmapOptions.CpuRead))
map=bm.map(SharpDX.Direct2D1.MapOptions.Read);
其他的
抛出新异常(“无法从Direc2D1.Bitmap1转换为GorgonImage”);
var size=bm.PixelSize.Width*bm.PixelSize.Height*4;
字节[]字节=新字节[大小];
Marshal.Copy(map.DataPointer,字节,0,大小);
IGorgonImageInfo=new GorgonImageInfo(ImageType.Image2D,BufferFormat.R8G8B8A8_UNorm)
{
宽度=bm.PixelSize.Width,
高度=bm.PixelSize.Height,
};
GorgonImage nqi=新的GorgonImage(信息);
不安全的
{
对于(int y=0;y>8);
g=(字节)((字节[位置+1]*div_alpha+0x80)>>8);
b=(字节)((字节[位置+2]*div_alpha+0x80)>>8);
}
}
其他的
{
r=字节[位置+1];
g=字节[位置+2];
b=字节[位置+3];
}
SharpDX.Color4 cl4=新的SharpDX.Color4((浮点)r/255.0f,(浮点)g/255.0f,(浮点)b/255.0f,(浮点)alpha/255.0f);
//DXGI格式的命名法有点混乱,因为我们倾向于认为布局是最高的
//最低,但事实上,它是从最低到最高的。
//因此,即使DXGI格式是RGBA,我们也必须转换为ABGR。内存布局是从最底层开始的
//(R在字节0)到最高字节(A在字节3)。
//因此,R是最低字节,A是最高字节:A(24),B(16),G(8),R(0)。
int*destBuffer=(int*)(不安全的.AsPointer(参考nqi.Buffers[0]。数据[destOffset]);
*destBuffer=cl4.ToRgba();//color.ToABGR();
//offset++;
偏移量+=4;
}
}
}
返回nqi;
}
问题是,对于大小为(1280,720)的SharpDX位图。转换后的图像正常:
但是使用大小为(1281,720)的SharpDX位图。convert函数不能正常工作。我得到了这张转换后的图像:
我无法找出我的代码有什么问题。你们能帮我指出问题所在吗?谢谢
以下是我使用的蛇发女怪类型:
包裹时的这种倾斜通常是一个步幅与宽度的问题。您可以使用倾斜的方向(与行顺序结合使用,通常是自上而下,但并不总是如此)来查看它是源地址计算中的问题还是目标地址计算中的问题。这里的倾斜角度是“向后”的,这意味着src地址前进得太慢,因此像素相对于应该的位置越来越向右和向下。原则上,目标地址前进过快可能会造成相同的影响,但这种情况不太可能发生(步幅与宽度的问题不会造成这种情况,可能会使用错误的步幅) 因此,
位置
是错误的,(y*info.Width+x)*4
使用宽度而不是可疑的步幅
源跨距是
map。俯仰
因此位置
应该是y*map。俯仰+4*x
在执行封送.复制
步骤后,数据是否正确?它没有考虑到map.Pitch
,所以我觉得它有点可疑,但是idk.(y*info.Width+x)*4
,这不是一个大步吗?类似于y*stride+4*x
这将是源跨步,因此map.Pitch
我也添加了一些解释。顺便说一句,您不需要整个SharpDX.Color4
浮点分区,您可以将这些RGB a字节填充到目标中;nqi.ImageData[destOffset+1]=g代码>