首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将图片合并成WriteableBitmap?

如何将图片合并成WriteableBitmap?
EN

Stack Overflow用户
提问于 2014-09-08 14:56:07
回答 2查看 1.9K关注 0票数 4

我有这样的位图:

代码语言:javascript
复制
var map = new WriteableBitmap(800,800,800,800, PixelFormats.Bgr32,null);

然后我有一个50x50PNG图片,我想合并到这个位图(包括透明度)的位置偏移顶部100左150 (从左上角的位图)。

代码语言:javascript
复制
var img = new BitmapImage(new Uri(@"D:\test.png", UriKind.Absolute));

我尝试过类似map.WritePixels(img);之类的东西,但这只会引发一个错误。如何将此图像合并到位图中?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-09-08 17:17:27

只需将颜色值复制到缓冲区,然后将其复制回WriteableBitmap

代码语言:javascript
复制
public void Chubs_BitBltMerge(ref WriteableBitmap dest, int nXDest, int nYDest, ref BitmapImage src)
{
    // copy the source image into a byte buffer
    int src_stride = src.PixelWidth * (src.Format.BitsPerPixel >> 3);
    byte[] src_buffer = new byte[src_stride * src.PixelHeight];
    src.CopyPixels(src_buffer, src_stride, 0);

    // copy the dest image into a byte buffer
    int dest_stride = src.PixelWidth * (dest.Format.BitsPerPixel >> 3);           
    byte[] dest_buffer = new byte[(src.PixelWidth * src.PixelHeight) << 2];
    dest.CopyPixels(new Int32Rect(nXDest, nYDest, src.PixelWidth, src.PixelHeight), dest_buffer, dest_stride, 0);

    // do merge (could be made faster through parallelization)
    for (int i = 0; i < src_buffer.Length; i = i + 4)
    {
        float src_alpha = ((float)src_buffer[i + 3] / 255);
        dest_buffer[i + 0] = (byte)((src_buffer[i + 0] * src_alpha) + dest_buffer[i + 0] * (1.0 - src_alpha));
        dest_buffer[i + 1] = (byte)((src_buffer[i + 1] * src_alpha) + dest_buffer[i + 1] * (1.0 - src_alpha));
        dest_buffer[i + 2] = (byte)((src_buffer[i + 2] * src_alpha) + dest_buffer[i + 2] * (1.0 - src_alpha));
    }

    // copy dest buffer back to the dest WriteableBitmap
    dest.WritePixels(new Int32Rect(nXDest, nYDest, src.PixelWidth, src.PixelHeight), dest_buffer, dest_stride, 0);
}

代码语言:javascript
复制
public MainWindow()
{
    InitializeComponent();

    BitmapImage texture = new BitmapImage(new Uri("50x50.png", UriKind.Relative));

    Image background = new Image();
    background.Source = new BitmapImage(new Uri("backdrop.png", UriKind.Relative));
    WriteableBitmap wb = new WriteableBitmap((BitmapSource)background.Source);

    // bit the 50x50 onto the backdrop
    Chubs_BitBltMerge(ref wb, 150, 100, ref texture);

    // set the result to an Image in XAML to see the result
    //this.myImage.Source = wb;
    //this.myImage.Width = wb.PixelWidth;
    //this.myImage.Height = wb.PixelHeight;

}

票数 3
EN

Stack Overflow用户

发布于 2020-10-23 09:52:39

在计算alpha通道的值时,请确保正在对浮点值进行除法,例如,使用255.0而不是255个,否则当alpha = 255时只得到src_alpha =1,否则只得到src_alpha =0时。虽然变化很小,但在半透明的情况下影响很大。所以我的解决方案是这样的:

代码语言:javascript
复制
    public void Chubs_BitBltMerge(ref WriteableBitmap dest, int nXDest, int nYDest, ref BitmapImage src)
    {
        // copy the source image into a byte buffer
        int src_stride = src.PixelWidth * (src.Format.BitsPerPixel >> 3);
        byte[] src_buffer = new byte[src_stride * src.PixelHeight];
        src.CopyPixels(src_buffer, src_stride, 0);

       // copy the dest image into a byte buffer
       int dest_stride = src.PixelWidth * (dest.Format.BitsPerPixel >> 3);           
       byte[] dest_buffer = new byte[(src.PixelWidth * src.PixelHeight) << 2];
       dest.CopyPixels(new Int32Rect(nXDest, nYDest, src.PixelWidth, src.PixelHeight), dest_buffer, dest_stride, 0);

       // do merge (could be made faster through parallelization)
       for (int i = 0; i < src_buffer.Length; i = i + 4)
       {
           float src_alpha = (float)(src_buffer[i + 3] / 255.0);
           dest_buffer[i + 0] = (byte)((src_buffer[i + 0] * src_alpha) + dest_buffer[i + 0] * (1.0 - src_alpha));
           dest_buffer[i + 1] = (byte)((src_buffer[i + 1] * src_alpha) + dest_buffer[i + 1] * (1.0 - src_alpha));
           dest_buffer[i + 2] = (byte)((src_buffer[i + 2] * src_alpha) + dest_buffer[i + 2] * (1.0 - src_alpha));
       }

       // copy dest buffer back to the dest WriteableBitmap
       dest.WritePixels(new Int32Rect(nXDest, nYDest, src.PixelWidth, src.PixelHeight), dest_buffer, dest_stride, 0);
    }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25727167

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档