Welcome Guest! To enable all features, please Login or Register.

Notification

Icon
Error

Options
View
Last Go to last post Unread Go to first unread post
#1 Posted : Tuesday, March 12, 2013 12:21:13 PM(UTC)

dh0well  
dh0well

Groups: Registered
Posts: 7


Drawing vector graphics onto a transparent background canvas has caused me a little grief while evaluating your SDK. It's all a matter of getting me to understand the steps, so could I get some insight into how to handle this?

I am basically just:
a. Loading an SVG file using LVectorFile
b. Using a derived LVectorBase
c. Creating an LBitmapBase to Realize() onto
d. Using ConvertToDIB() to get an HDIBI
e. Making a Gdiplus::Bitmap with the (int, int, int, PixelFormat*, byte) constructor

The resulting image is 100% transparent (all the alpha channel bytes are 0x00).

The only way I could get it to work was to set a solid background color (used Gdiplus::Color::HotPink) and then edit the bits in the DIB to 0xFF unless they are my special background color. This doesn't work so well if the SVG (or any other vector file format) contains that color.

Is my expectation that I can create a blank canvas with a transparent background and have the LeadTools API render the vector graphic elements onto it flawed? The translation to DIB/GDI+ seems to be the problem area.
 

Try the latest version of LEADTOOLS for free for 60 days by downloading the evaluation: https://www.leadtools.com/downloads

Wanna join the discussion? Login to your LEADTOOLS Support accountor Register a new forum account.

#2 Posted : Tuesday, March 12, 2013 12:24:58 PM(UTC)

dh0well  
dh0well

Groups: Registered
Posts: 7


Pardon my formatting, the preview led me to believe I had to add the paragraph breaks. :-(

Here is some pseudo-C++ illustrating my initial, unsuccessful attempt:

Steps to load and render vector (SVG) file
(error checking omitted for clarity)


LBase::LoadLibraries( LT_KRN )

class MyVector : LVectorBase
{
}

MyVector owner;

std::string filename = L"...svg";

LVectorFile svgfile( owner, const_cast( filename.c_str() ) );

svgfile.LoadFile();

#include
Gdiplus::Bitmap MyVector::GetBitmap()
{
L_UINT width = ...;
L_UINT height = ...;

// Expectation: to create a transparent background canvas in which to draw
// vector graphic elements onto.

const Gdiplus::Color bgcolor( static_cast( Gdiplus::Color::Transparent ) ); // 0x00FFFFFF
COLORREF bgcolorref = bgcolor.ToCOLORREF();

SetBackgroundColor( bgcolorref );

LBitmapBase bmpBase( width, height, bbp, ORDER_BGR, NULL, TOP_LEFT, bgcolorref );

// Required in order to get transparency to work
// (in spite of, but in conjunction with SetBackgroundColor call above)

pBITMAPHANDLE pBmpBaseHandler = bmpBase.GetHandle();
pBmpBaseHandler->Flags.Transparency = 1;
pBmpBaseHandler->Transparency = bgcolorref;

RECT vp = { 0, 0, width, height };
SetViewport( &vp );

Realize( bmpBase );

bmpBase.Save( L"...png", FILE_PNG, 0, 1, 0 ); // First result: produces image with desired transparency


// Next step: conversion to GDI+ Bitmap

HDIB hDIB = bmpBase.ConvertToDIB( DIB_BITMAPV5HEADER ); // taking care not to use DIB_BITMAPINFOHEADER

byte* pDIB = static_cast( ::GlobalLock( hDIB ) );

PBITMAPV5HEADER pbih = reinterpret_cast( pDIB );
pBits = pDIB + pbih->biSize;

const L_UINT bbp = 32; // bits/pixel
const int bpB = 8; // bits/Byte
int stride = ( bbp / bpB ) * width;

Gdiplus::Bitmap gdiplusbitmap( width, height, stride, PixelFormat32bppARGB, pBits );

CLSID clsid = Gdiplus::GetImageEncoders()...; // yada, yada, yada, returns clsid;

gdiplusbitmap.Save( L"...png", &clsid ); // Result: image is 100% transparent (every pixel has alpha byte == 0x00)

(void)::GlobalUnlock( hDIB );
}
 
#3 Posted : Thursday, March 14, 2013 11:23:16 AM(UTC)

Amin  
Amin

Groups: Manager, Tech Support
Posts: 353


If I understand correctly, the required result is a bitmap image that has an alpha channel, where all pixels are transparent except those that correspond to the objects from the source vector drawing.

If this is correct, you can actually do it completely using LEADTOOLS without having to work with GDI, but you will need to find a working color that does not exist in the drawing objects.

The main steps are (all using LEADTOOLS functions):
1. Create a temporary bitmap and fill it with the working color.
2. Render the vector drawing on the temp bitmap.
3. Take a copy to be the main bitmap.
4. Create a region in the temp bitmap that corresponds to the working color pixels and fill it with black.
5. Invert the region and fill it with white.
6. Cancel the region and change the temp bitmap to 8-bit grayscale.
7. Set the temp bitmap as the alpha channel of the main bitmap.

If you would like C++ code, please confirm whether requirements are correct send me a sample drawing. If you want to attach files, put them in a ZIP or RAR file and do not use the "Preview" feature.

Amin Dodin

Senior Support Engineer
LEAD Technologies, Inc.
LEAD Logo
 
#4 Posted : Thursday, March 14, 2013 12:42:36 PM(UTC)

dh0well  
dh0well

Groups: Registered
Posts: 7


Thank you for the reply. Yes, your understanding of my question is exactly right (that "the required result is a bitmap image that has an alpha channel, where all pixels are transparent except those that correspond to the objects from the source vector drawing").

Please show me some C++ code to accomplish what you have suggested. A sample of this is in the attached ZIP file. In the ZIP, the input file is "BrightIdea.svg" and the expected result is shown in the attached "GdiplusBitmap.png"
File Attachment(s):
TransparentVectorBitmap.zip (5kb) downloaded 29 time(s).
 
#5 Posted : Sunday, March 17, 2013 6:58:19 AM(UTC)

mohamed  
mohamed

Groups: Registered, Tech Support
Posts: 179


Please try the following code that takes SVG vector file then saves it as PNG file with alpha.

+==================================================+
L_INT nRet;
LVectorBase Vector;
RECT VecRect;
VecRect.left = 0;
VecRect.top = 0;
VecRect.right = 400;
VecRect.bottom = 400;
nRet = Vector.Load(L"C:\\BrightIdea.svg");
if(nRet != SUCCESS)
{
    AfxMessageBox(L"Failed to Load SVG Image");
}   
nRet = Vector.AttachToWindow(m_hWnd);
nRet = Vector.SetViewport(&VecRect);
nRet = Vector.GetViewport(&VecRect);
LBitmapBase TempBitmap(  400 , 400, 24, ORDER_BGR, NULL, TOP_LEFT,RGB(255,105,180));
HDC TempDC = TempBitmap.CreateLeadDC();    
nRet = Vector.Paint(TempDC,FALSE);
TempBitmap.DeleteLeadDC(TempDC);     
LBitmapBase MainBitmap(400 , 400, 24, ORDER_BGR, NULL, TOP_LEFT,RGB(255,105,180));
nRet = MainBitmap.Copy(TempBitmap);    
LBitmapRgn Region(&TempBitmap);
nRet =Region.SetRgnColor(RGB(0,0,0));
TempBitmap.Fill(RGB(255,255,255));
Region.Free();    
nRet =Region.SetRgnColor(RGB(255,105,180));
TempBitmap.Fill(RGB(0,0,0));
Region.Free();    
nRet = TempBitmap.GrayScale(8);
nRet = MainBitmap.ColorRes(32);
nRet = MainBitmap.SetAlpha(TempBitmap);
nRet = MainBitmap.Save(L"c:\\FinalRes.png",FILE_PNG,32,2,0,NULL);
+==================================================+

Mohamed Abedallah
Developer Support Engineer
LEAD Technologies, Inc.

LEAD Logo
 
#6 Posted : Tuesday, March 19, 2013 3:42:58 AM(UTC)

dh0well  
dh0well

Groups: Registered
Posts: 7


That code segment didn't work for me. The PNG output at each stage of your algorithm is attached.

One of the things that I didn't make clear in my original question was that I need to produce a GDI+ bitmap in order to work within our legacy application.

I was able to get the result that I expected by manually editing the bits array prior to the construction of the desired Gdiplus::Bitmap. I.e.,

==
COLORREF bgcolorref = ...; // unique color

LBitmapBase bmpBase( width, height, 32, ORDER_BGR, NULL, TOP_LEFT, bgcolorref );

Realize( bmpBase );

HGLOBAL hDIB = bmpBase.ConvertToDIB( DIB_BITMAPV5HEADER );

byte* pDIB = static_cast( ::GlobalLock( hDIB ) );
PBITMAPV5HEADER pbih = reinterpret_cast( pDIB );

byte* pCurByte = pBits;

bool bottomUpDIB = pbih->bV5Height > 0; // http://msdn.microsoft.co...windows/desktop/dd407212(v=vs.85).aspx

for ( L_UINT row = 0; row (stride) : stride,
PixelFormat32bppARGB,
bottomUpDIB ? &pBits[(height-1) * stride] : pBits ); // http://support.microsoft.com/kb/317309

(void)::GlobalUnlock( hDIB );

==

This too relies on the use of a color that does not occur in the source bitmap just as your algorithm expects. Guess I will have to go with that for now.
File Attachment(s):
LBitmapBasePNGs.zip (18kb) downloaded 26 time(s).
 
#7 Posted : Tuesday, March 19, 2013 5:39:50 AM(UTC)

mohamed  
mohamed

Groups: Registered, Tech Support
Posts: 179


I checked your images and they don't contain the "FinalRes.png" or any 32-bit PNG file. Please download the attached project and test as follows:
1. Copy the Project folder to the following folder:
[LEADTOOLS 18]\Examples\ClassLibrary\MSVC\
2. Change the source SVG image location in the code and the result PNG 32-bit image location as well.
3. Build and run the project.
4. After running the application click on "Test Vector" menu item then click "Start Testing".
5. Check the Result 32-bit PNG file using our Main Raster demo. The image should open with transparency when painting using GDI+.

I am attaching the result 32-bit PNG image that I got on my side.

File Attachment(s):
LoadSave_2010.zip (51kb) downloaded 28 time(s).
Mohamed Abedallah
Developer Support Engineer
LEAD Technologies, Inc.

LEAD Logo
 
#8 Posted : Tuesday, March 19, 2013 6:42:12 AM(UTC)

dh0well  
dh0well

Groups: Registered
Posts: 7


Hmm, wonder why mine doesn't work? One thing my version does not do is the AttachToWindow (am using a console app).

Would you mind trying this SVG file (Pie.svg attached)? It has a milky appearance in the FinalRes.png.

There should be 5 PNG files in my earlier attachment. Is there nothing in the file? It looks okay when I download it from here. I used jZip to create it, but that shouldn't really matter.
 
#9 Posted : Tuesday, March 19, 2013 6:44:04 AM(UTC)

dh0well  
dh0well

Groups: Registered
Posts: 7


Oops, attaching as ZIP (didn't like me giving just a SVG file)
File Attachment(s):
Pie.zip (47kb) downloaded 28 time(s).
 
#10 Posted : Thursday, March 21, 2013 7:08:05 AM(UTC)

mohamed  
mohamed

Groups: Registered, Tech Support
Posts: 179


My previous project handles the Image you sent me before, so I updated the project to handle all cases. Please download and try the attached project. if you face any problems please send me the details of the problem.
File Attachment(s):
ALL_SVG_2010.zip (42kb) downloaded 29 time(s).
Mohamed Abedallah
Developer Support Engineer
LEAD Technologies, Inc.

LEAD Logo
 
You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.

Powered by YAF.NET | YAF.NET © 2003-2019, Yet Another Forum.NET
This page was generated in 0.288 seconds.