这是一段代码片段,我尝试在WPF图像控件中的图形(Bgra32 3985x3443)上放置一个蓝点图标(Bgr32; 169x169)。
string s = new FileInfo(System.Reflection.Assembly.GetExecutingAssembly().Location).DirectoryName + "\\lg_dot.jpg";
BitmapImage icon = new BitmapImage(new Uri(s));
var baseLayer = img_BackgroundLayer.Source as BitmapImage;
WriteableBitmap composite = new WriteableBitmap(baseLayer);
int bytesPerPixel = (int)(icon.Format.BitsPerPixel + 7) / 8;
int stride = (int)(bytesPerPixel * icon.Width);
int size = stride * (int)icon.Height;
byte[] pixels = new byte[size];
icon.CopyPixels(pixels, stride, 0);
composite.WritePixels(new Int32Rect(0, 0, (int)icon.Width, (int)icon.Height), pixels, stride, 1000, 1000);
请注意,我将点(图标)放在(1000,1000)图像上。但是,当观察时,点的左上角不是(1000,1000),它大约是(760,760)。如果我试图将图标放在(2000,2000),它出现在大约(1520,1520)。图标出现的位置总是大约(0.76 * X,0.76 * Y),其中X和Y是目标坐标。
我想我知道这里发生了什么......将Bgr32图像放到Bgra32背景上有什么关系...但我不够聪明,看看如何解决它。
答案 0 :(得分:0)
每像素字节公式:
(bits per pixel + 7) / 8
步伐公式:
bytes per pixel * image width
注意字节和位并使用整数进行计算!
因此对于1024像素宽的图像:
Bgr32
(24 + 7) / 8 = 3
3 * 1024 = 3072
Bgra32
(32 + 7) / 8 = 4
4 * 1024 = 4096
查看您的代码:
步幅应为3,而不是4:D
您不必使用步幅int[]
,请记住sizeof(int) == 4
byte
byte[]
图片数组中像素的偏移量:每像素stride * y + x *字数
int
int[]
图像数组中像素的偏移量:y * width + x
顺便问一下,您是否检查过Image.Stretch是否设为None
?
最后,请注意组件顺序:
BGRA代表ARGB(如果A为0,你可能看不到任何东西,你认为你已经设置了B)
最后提示:https://writeablebitmapex.codeplex.com/最终可能对您更容易。
修改强>
这非常糟糕,在我的情况下它是空的,因为BitmapFrameDecode
无法转换为BitmapImage
,最好保留对源的引用:
var baseLayer = Image1.Source as BitmapImage;
我给你的公式是正确的,我只需改变destX和destY,因为我的背景不像你的那么大。
var icon = new BitmapImage(new Uri("..\\..\\avatar92.jpg", UriKind.Relative));
var background = new BitmapImage(new Uri("..\\..\\canary_1024_600_a_0.jpg", UriKind.Relative));
var writeableBitmap = new WriteableBitmap(background);
int bytesPerPixel = (icon.Format.BitsPerPixel + 7) / 8;
int stride = bytesPerPixel * icon.PixelWidth;
int size = stride * icon.PixelHeight;
var pixels = new byte[size];
icon.CopyPixels(pixels, stride, 0);
writeableBitmap.WritePixels(new Int32Rect(0, 0, icon.PixelWidth, icon.PixelHeight), pixels, stride, 500, 500);
Image1.Source = writeableBitmap;
再次
Image.Stretch
== None
?这与WriteableBitmapEx的结果相同,而不必处理所有细节,例如stride,array,bpp等......
var icon = new BitmapImage(new Uri("..\\..\\avatar92.jpg", UriKind.Relative));
var background = new BitmapImage(new Uri("..\\..\\canary_1024_600_a_0.jpg", UriKind.Relative));
var img1 = BitmapFactory.ConvertToPbgra32Format(icon);
var img2 = BitmapFactory.ConvertToPbgra32Format(background);
var img1Size = new Size(img1.PixelWidth, img1.PixelHeight);
img2.Blit(new Rect(new Point(500, 500), img1Size), img1, new Rect(img1Size));
Image1.Source = img2;
如果您更喜欢这种方式,请确保您的位图具有相同的格式:FormatConvertedBitmap
如果仍然无法正常使用,请发布Short, Self Contained, Correct (Compilable), Example并链接到这两个图片,以便人们可以真的帮助您。我没有在你的代码中找到任何内容,所以我猜有些东西不对,但是因为你还没有粘贴我们无法辨认的所有代码。