-
December 20th, 2012, 01:45 AM
#1
Gifdecoder,BitmapSource and System.Windows.Controls::Image in mfc
hi.
first of all sorry for my bad english.
i need make a CBitmap or a streamdata from a System.Windows.Controls::Image(rendered out put)in a SDI mfc application (supporting \clr).
here is my codes:
Code:
using namespace System;
using namespace System::IO;
using namespace System::Collections::Generic;
using namespace System::Windows;
using namespace System::Windows::Controls;
using namespace System::Windows::Media;
using namespace System::Windows::Media::Imaging;
using namespace System::Threading;
using namespace System::Security;
bool CGifdecoder::Decoder()
{
UINT Stride;
unsigned short *res;
unsigned short Buff[ROW * COLUMN];
BitmapSource^ bitmapSource ;
String ^ str = gcnew String(Files[m_Current].Filepath);
// Open a Stream and decode a GIF image
Stream^ imageStreamSource = gcnew FileStream(str, FileMode::Open, FileAccess::Read, FileShare::Read);
GifBitmapDecoder^ decoder = gcnew GifBitmapDecoder(imageStreamSource, BitmapCreateOptions::PreservePixelFormat, BitmapCacheOption::Default);
GifInfo[m_Current].Frames = decoder->Frames->Count;
for(int i = 0;i < GifInfo[m_Current].Frames;i++){
Init_ReadDecodedBits();
bitmapSource = decoder->Frames[i];
bpp = bitmapSource->Format.BitsPerPixel;
Stride = (UINT)(bitmapSource->PixelWidth*(bitmapSource->Format.BitsPerPixel / 8) + 3) & (~3);//bitmapSource->PixelWidth * ((bitmapSource->Format.BitsPerPixel + 7) / 8);
res = new unsigned short[bitmapSource->PixelHeight*bitmapSource->PixelWidth];
IntPtr intptr = IntPtr(res);
bitmapSource->CopyPixels(System::Windows::Int32Rect::Empty
,intptr,Stride*bitmapSource->PixelHeight, Stride);
for(long j = 0;j<bitmapSource->PixelHeight*bitmapSource->PixelWidth;j++)
Buff[j]=ReadParseData(bpp,res);
//here i got unrendered codes from bitmapSource
delete res;
}
}
by this codes i can read datastream from bitmapSource but in this way somthing goes wrong in most of GIF animations.
after debug i found out i need 3 more things too decode a gif animation - (x,y) position and size of each frame and disposal method for each one - finally i just found a way to draw true images on a form window by this codes:
Code:
System::Windows::Window^ mainWindow;
mainWindow = gcnew System::Windows::Window();
mainWindow->Title = "GIF Imaging Sample";
//ScrollViewer^ mySV = gcnew ScrollViewer();
array<System::Byte>^ pixels = gcnew array<System::Byte>(bitmapSource->PixelHeight * Stride);
bitmapSource = decoder->Frames[0];
Image^ myImage = gcnew Image();
myImage->Source = bitmapSource;
myImage->Stretch = Stretch::None;
myImage->Margin = System::Windows::Thickness(0);
StackPanel^ myStackPanel = gcnew StackPanel();
myStackPanel->Orientation = Orientation::Vertical;
myStackPanel->VerticalAlignment = VerticalAlignment::Stretch;
myStackPanel->HorizontalAlignment = HorizontalAlignment::Stretch;
myStackPanel->Children->Add(myImage);
// mySV->Content = myStackPanel;
mainWindow->Content = myStackPanel;//mySV;
mainWindow->Width = bitmapSource->PixelHeight;
mainWindow->Height = bitmapSource->PixelHeight;
//mainWindow->ResizeMode = System::Windows::ResizeMode::NoResize;
mainWindow->Show();
when i change
Code:
bitmapSource = decoder->Frames[0];
to
Code:
bitmapSource = decoder->Frames[1];
frame[1] has drawn perfectly on window(i think some how Image class takes care about - (x,y) position and size of each frame and disposal method for each one ),so im wonder if how can i make a CBitmap or a data stream from System.Windows.Controls::Image class to use in mfc app.
best regards.
-
December 20th, 2012, 11:12 AM
#2
Re: Gifdecoder,BitmapSource and System.Windows.Controls::Image in mfc
You appear to do a lot of bit shuffling yourself, so I see the need to ask: If this is an MFC app anyway and your goal is to get a CBitmap out of a GIF image, then why are you using all that rather WPF-oriented stuff from the .NET framework library in the first place? The System::Drawing::Bitmap class is a wrapper for a GDI+ bitmap object, so it may dramatically simplify what you're trying to do here.
You wouldn't even need to create the file stream yourself: You can directly construct a Bitmap object by just passing the image file name to the respective contructor overload. The class has member functions to obtain a HBITMAP for the image which you then can simply pass to CBitmap::FromHandle(). For a more low-level access you may also get hands on the actual bitmap representation in memory, in case that's even needed in your scenario. I have never used it with multi-frame images myself, but it has a SelectActiveFrame() method that's obviously meant to support such a scenario.
Finally, I ask myself why there shouldn't be something in MFC (my MFC and Win32 is rather rusty at the time though) or the GDI/GDI+ APIs that may allow you to eliminate the need for .NET code altogether. GDI+ looks like a really good candidate. Well, at least CBitmap itselft seems to not support direct loading of images (even less muli-frame images).
You did use code tags but the weird and almost non-existent indentation still makes your code quite hard to read. However, the display of HTML entities instead of characters like > probably isn't your fault; I suspect that to be a glitch of the forum software. At least I've already seen something like that since the recent forum software update, and, IIRC, a simple workaround fix is to click Edit on your post and then just re-submit it without actually having edited anything.
Last edited by Eri523; December 29th, 2012 at 08:39 AM.
I was thrown out of college for cheating on the metaphysics exam; I looked into the soul of the boy sitting next to me.
This is a snakeskin jacket! And for me it's a symbol of my individuality, and my belief... in personal freedom.
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|