none
如何在 swapchainbackgroudpanel 中显示两张图片通过Alpha通道合并的效果 RRS feed

  • 问题

  • 大家好:

        我在做一个DirectX的Metro app, 其中涉及到将两张图片合并显示的问题,具体来说是在一张底版上将第二张图片叠加上去,就是通过Alpha通道实现叠加的效果。我的数据格式是B8G8R8A8,但是Swapchainbackgroudpanel 支持的这种pixel format中对应的alpha mode只有PREMULTILIPLIED和IGNORE. 然后发现第二张图片的alpha通道不起作用:我手工写一个buffer,无论buffer里的数据全部写成0XFF00FF00还是0X0000FF00都显示一个纯绿色。

    我的基本code的逻辑:

    Create swapchainbackgroudpanel : pixel format 设置: DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIPED,

    =>Create targetBitmap 采用同样的pixel format, d2d1Context->setTarget()设置为target

    => Create bitmap1和bitmap2  同样的pixel format

    显示的时候:

    // 先拷贝底版

      bitmap2->CopyFromBitmap(bitmap1);

    // 拷贝需要叠加的图像数据

     buffer[] = {0X000FF00..}; 

      bitmap2->CopyFromMemory(buffer...);

    md2dContext->BeginDraw();

    md2dContext->DrawImage(bitmap2->Get(), (0,0), rc, D2D1_INTERPOLATION_MODE_LINER, D2D1_COMPOSITE_MODE_BOUNDED_SOURCE_COPY);

    md2dContext->EndDraw();

    非常感谢!!!!

    2013年10月24日 1:55

答案

  • Microsoft::WRL::ComPtr<ID2D1Bitmap1>  bmp;    //已加载的原图
    Microsoft::WRL::ComPtr<ID2D1Bitmap1>  img;  
    		
    
    		D2D1_BITMAP_PROPERTIES1 prop1 = D2D1::BitmapProperties1(
    			D2D1_BITMAP_OPTIONS_CPU_READ | D2D1_BITMAP_OPTIONS_CANNOT_DRAW,
    			D2D1::PixelFormat(
    			DXGI_FORMAT_B8G8R8A8_UNORM,
    			D2D1_ALPHA_MODE_PREMULTIPLIED
    			)
    			);
    
    		D2D1_SIZE_U size = bmp.Get()->GetPixelSize();
    		m_d2dContext->CreateBitmap(
    			size, 
    			nullptr,
    			0,
    			&prop1,
    			&img
    			);
    
    		D2D1_RECT_U rect = {0, 0,size.width, size.height};
    		D2D1_POINT_2U point = {0, 0};
    		img->CopyFromBitmap(&point, bmp.Get(), &rect);  
    
    		D2D1_MAP_OPTIONS options = D2D1_MAP_OPTIONS_READ;
    		D2D1_MAPPED_RECT mappedRect;
    		img->Map(options, &mappedRect);
    		UINT32 pitch = mappedRect.pitch;
    		Array<byte>^ pData = ref new Array<byte>(pitch*size.height); 
    		memcpy(pData->Data, mappedRect.bits, pitch * size.height);
    
    		int ptr=0;
    		for( int row = 0 ; row < size.height ; row ++ ) 
    		{ 
    			for( int col = 0 ;  col < size.width ;  col ++ ) 
    			{ 
    
                                    byte B = pData[ptr];
                                    byte G = pData[ptr+1];
                                    byte R = pData[ptr+2];
    				byte A = pData[ptr+3];
    				ptr += 4;
    			} 
    			ptr += pitch - size.width* 4; 
    		} 
    		img->Unmap();	

    取出要复合的两张图的像素数组,自己写需要的复合算法。


    • 已编辑 Fenty000 2013年10月31日 1:49
    • 已标记为答案 wd0623 2013年11月1日 1:04
    2013年10月31日 1:46

全部回复

  •   Direct2D 中由个API   FillOpacityMask ,将一个带有alpha通道的图 当做mask,另一个图构成位图画刷,合并出效果。


     

    2013年10月25日 2:04
  •   Direct2D 中由个API   FillOpacityMask ,将一个带有alpha通道的图 当做mask,另一个图构成位图画刷,合并出效果。


     

    非常感谢您的回复!! 在相关的文档上和demo里边我看到用作mask的图是简单的纯色图,而且文档上说的是像素的颜色信息被忽略,那么请问您如果我要去叠加的两张图片的像素信息也就是RGB值都需要,使用这个函数还能解决么?  

    其实我所需要的就是这样:

    R = R1*ALPHA/255 + R2*(255-ALPHA)/255

    G = G1*ALPHA/255 + G2*(255-ALPHA)/255

    B = B1*ALPHA/255 + B2*(255-ALPHA)/255

    谢谢 !

    2013年10月29日 10:01
  • Microsoft::WRL::ComPtr<ID2D1Bitmap1>  bmp;    //已加载的原图
    Microsoft::WRL::ComPtr<ID2D1Bitmap1>  img;  
    		
    
    		D2D1_BITMAP_PROPERTIES1 prop1 = D2D1::BitmapProperties1(
    			D2D1_BITMAP_OPTIONS_CPU_READ | D2D1_BITMAP_OPTIONS_CANNOT_DRAW,
    			D2D1::PixelFormat(
    			DXGI_FORMAT_B8G8R8A8_UNORM,
    			D2D1_ALPHA_MODE_PREMULTIPLIED
    			)
    			);
    
    		D2D1_SIZE_U size = bmp.Get()->GetPixelSize();
    		m_d2dContext->CreateBitmap(
    			size, 
    			nullptr,
    			0,
    			&prop1,
    			&img
    			);
    
    		D2D1_RECT_U rect = {0, 0,size.width, size.height};
    		D2D1_POINT_2U point = {0, 0};
    		img->CopyFromBitmap(&point, bmp.Get(), &rect);  
    
    		D2D1_MAP_OPTIONS options = D2D1_MAP_OPTIONS_READ;
    		D2D1_MAPPED_RECT mappedRect;
    		img->Map(options, &mappedRect);
    		UINT32 pitch = mappedRect.pitch;
    		Array<byte>^ pData = ref new Array<byte>(pitch*size.height); 
    		memcpy(pData->Data, mappedRect.bits, pitch * size.height);
    
    		int ptr=0;
    		for( int row = 0 ; row < size.height ; row ++ ) 
    		{ 
    			for( int col = 0 ;  col < size.width ;  col ++ ) 
    			{ 
    
                                    byte B = pData[ptr];
                                    byte G = pData[ptr+1];
                                    byte R = pData[ptr+2];
    				byte A = pData[ptr+3];
    				ptr += 4;
    			} 
    			ptr += pitch - size.width* 4; 
    		} 
    		img->Unmap();	

    取出要复合的两张图的像素数组,自己写需要的复合算法。


    • 已编辑 Fenty000 2013年10月31日 1:49
    • 已标记为答案 wd0623 2013年11月1日 1:04
    2013年10月31日 1:46
  • Microsoft::WRL::ComPtr<ID2D1Bitmap1>  bmp;    //已加载的原图
    Microsoft::WRL::ComPtr<ID2D1Bitmap1>  img;  
    		
    
    		D2D1_BITMAP_PROPERTIES1 prop1 = D2D1::BitmapProperties1(
    			D2D1_BITMAP_OPTIONS_CPU_READ | D2D1_BITMAP_OPTIONS_CANNOT_DRAW,
    			D2D1::PixelFormat(
    			DXGI_FORMAT_B8G8R8A8_UNORM,
    			D2D1_ALPHA_MODE_PREMULTIPLIED
    			)
    			);
    
    		D2D1_SIZE_U size = bmp.Get()->GetPixelSize();
    		m_d2dContext->CreateBitmap(
    			size, 
    			nullptr,
    			0,
    			&prop1,
    			&img
    			);
    
    		D2D1_RECT_U rect = {0, 0,size.width, size.height};
    		D2D1_POINT_2U point = {0, 0};
    		img->CopyFromBitmap(&point, bmp.Get(), &rect);  
    
    		D2D1_MAP_OPTIONS options = D2D1_MAP_OPTIONS_READ;
    		D2D1_MAPPED_RECT mappedRect;
    		img->Map(options, &mappedRect);
    		UINT32 pitch = mappedRect.pitch;
    		Array<byte>^ pData = ref new Array<byte>(pitch*size.height); 
    		memcpy(pData->Data, mappedRect.bits, pitch * size.height);
    
    		int ptr=0;
    		for( int row = 0 ; row < size.height ; row ++ ) 
    		{ 
    			for( int col = 0 ;  col < size.width ;  col ++ ) 
    			{ 
    
                                    byte B = pData[ptr];
                                    byte G = pData[ptr+1];
                                    byte R = pData[ptr+2];
    				byte A = pData[ptr+3];
    				ptr += 4;
    			} 
    			ptr += pitch - size.width* 4; 
    		} 
    		img->Unmap();	

    取出要复合的两张图的像素数组,自己写需要的复合算法。


    非常感谢您的回复!!
    • 已标记为答案 wd0623 2013年11月14日 2:03
    • 取消答案标记 wd0623 2013年11月14日 2:04
    2013年11月1日 1:05