I have a Bitmap* (this is Visual C++ 6.0).
I need to save this Bitmap* to a bmp file. I've seen code on the internet that allows me to do this if I have an hDib. (handle to Dib). Given that I already have a CBitmap*, how can I obtain the hDib?
Or, if someone has an easier way to save a bitmap to a file, that would be great too. (This is VC++ 6.0 (1998) and I don't (think) I have access to CImage.
I'm going to assume you're actually asking about CBitmap and not Bitmap, as they're two different things.
CBitmap derives from CGdiObject, which has a member m_hObject that contains the handle.
It also has an operator HBITMAP which returns the handle - all you have to do is a cast.
HBITMAP hbmp = (HBITMAP) mybitmap;
Whether this handle is a DIB or not will depend on how you created the bitmap.
Related
I have acquired the .NET SVG.DLL and written a test harness to see if this DLL will solve an SVG problem I have, and in fact it has. Now ... for this BIG hurdle, I need to marshall or return the Bitmap, Image, or what ever is easiest method back to the main C++ code that needs the Bitmap.
Can anyone please help.
Al Harper
Well I seemed have have finally figure out how to get bitmap from managed to unmanaged cpp code. In short I used the HBITMAP handle retrieved in the managed code, then re hydrated a bitmap in the CPP code from it.
Let me know if anyone wants a code snippet.
Al Harper
Sorry about the short title, but I honestly can't get a better description of what is happening because I don't know enough...
Some background first, I am "converting" a multi-byte application to support unicode and I've made the standard char/string wchar_t/wstring changes and the my code is building without problems.
What happens is that when the application is being initialized it hits an assert when it registers the applications's document templates. The code is the standard
CMultiDocTemplate* pRepDocTemplate = NULL;
pRepDocTemplate = new CMultiDocTemplate(IDR_DIAGNOSTIC_REPORT_TYPE,
RUNTIME_CLASS(CDiagnosticReportDoc),
RUNTIME_CLASS(CChildFrame), // custom MDI child frame
RUNTIME_CLASS(CDiagnosticReportView));
and CDiagnosticsReportView has the standard DECLARE_DYNCREATE and IMPLEMENT_DYNCREATE in the header and source.
The assert is at doctmpl.cpp line 29 (mfc120ud.dll - at least is using the correct dll), but I can't find the source code anywhere to actually know what is happening.
The inheritance tree is pretty straightforward:
CDiagnosticReportView
\->CReportViewBase
\->CXTPReportView
\->CView
CXTPReportView is part of a framework that we are using which is provided by Codejock (Codejock extreme toolkitPro). From the build pane I know that it's linking against it's unicode debug dll (ToolkitPro1631vc120UD.dll)
Suffice to say that in the multibyte configuration this problem doesn't occur.
The project is configured to use the UNICODE character set (Project properties->Configuration Properties->General->Character Set).
Any help would be appreciated!
Thanks in advance!
It all had to do with the fact that I was linking against the non UNICODE build of Codejock. Even though I saw a reference to the UNICODE dll, the lib wasn't the correct one!
Problem was solved when I opened my eyes ;)
I am working on a vc++ forms code. I need to get the current directory to open the help form of the project. While I tried all the code which I could find on internet everything as the same problem. I am posting one of the code below. The output of the code is true or false it is not returning the string which as a current directory value.
TCHAR pwd[MAX_PATH];
GetCurrentDirectory(MAX_PATH, pwd);
MessageBox::Show(Convert::ToString(&pwd), "My Application", MessageBoxButtons::OKCancel, MessageBoxIcon::Asterisk);
please help me out how to know the current directory in VC++ forms
You are passing the address of the pointer to Convert::ToString(). pwd is an array and using the variable name without an array subscript automatically decays to a pointer. You want to use either
Convert::ToString(pwd)
or
Convert::ToString(&pwd[0])
You are using C++/CLI. In that case, you should use .NET functions, whenevver possible... so instead of "GetCurrentDirectory" you should use the property System::Environment::CurrentDirectory!
Alternatively you should disable /clr (.NET) support and only use native functions!
If you really want to mix native and managed code, you should use the constructor for String to convert from TCHAR:
String^ str = gcnew String(pwd);
I am trying to create a text file through my code. The file is created but its extension is different(not .txt). Then on searching i came to know that this can be because of MFC runtimes.
I searched for the MFC Runtimes in my C:\program Files\Windows CE tools\SDK but i am not able to find the MFC folder there. What should i do? from where should i include MFC Runtimes?
here's the text file generation code which i am using:
void CFormRight::OnBnClickedButtonTextfile()
{
CFile File;
char cFileAddr[100] = {"My Device\\Label.txt"};
File.Open((LPCTSTR)cFileAddr, CFile::modeCreate | CFile::typeBinary |CFile::modeWrite | CFile::shareDenyNone);
File.Write("Hello World", 15);
File.Close();
}
If you're just looking for the DLLs, try looking on your development machine here:
%PROGRAM_FILES%\Microsoft Visual Studio 9.0\VC\ce\dll
That gets you the actual libraries. Including them in the OS image can be done a variety of ways. Typically you'd add them to your platform or project BIB file.
Even with all of that, though, I don't think it's going to solve your problem of a file extension. If you're creating a file and it shows up, just without an extension, it has nothing to do with MFC being there or not, it has to do with either your code, or the way you're determining there is no extension (is "hide file extensions" turned on in Explorer?). To solve that problem, we'd need to see code.
** Edit **
Windows CE is heavily biased toward Unicode. Nearly all Win32 APIs only have the Unicode variant exposed, therefore your code should also lean toward Unicode, meaning string you pass around that will end up at API calls should be Unicode.
Second, you should not ignore the compiler when it complains. The cast you have in there I bet was due to a compiler complaint, and it's just incorrect. If your original code was this (note the lack of cast on the first parameter):
File.Open(cFileAddr, CFile::modeCreate | CFile::typeBinary |
CFile::modeWrite | CFile::shareDenyNone);
Then you would get a compiler error:
error C2664: 'CFile::Open' : cannot convert parameter 1 from 'char [100]' to 'LPCTSTR'
That's because under Windows CE, Open is looking for a wide (Unicode) string. You have an ANSI string. You cannot convert from ANSI to Unicode through a simple direct cast like you did. Yes, the compiler will quit complaining, but it gives bad behavior. You can cast an int to a char[] too, but that doesn't mean it will work for the API.
So change your code to use wide strings and all will work:
CFile File;
CFileException ex;
wchar_t cFileAddr[100] = TEXT("My Device\\Label.txt");
if(!File.Open(cFileAddr, CFile::modeCreate | CFile::typeBinary |
CFile::modeWrite | CFile::shareDenyNone))
{
wchar_t error[1024];
ex.GetErrorMessage(error, 1024);
cout << "Error opening file: ";
cout << error;
return;
}
File.Write("ID Technologies", 15);
File.Close();
Note the use of wchar_t, the initialization using the TEXT macro, and the lack of the cast in the Open call.
EDIT 2
I added error handling in the code above, but really you should learn to read the documentation and how to debug. This is a pretty basic usage scenario, and knowing how to look for errors is critical.
I'm porting an OpenCV 2.2 app from Unix (that works) onto Windows 7 64-bit and I receive the following exception when cv::imwrite is called
"OpenCV Error: Unspecified error (could not find a writer for the specified extension) in unknown function, file highgui\src\loadsave.cpp"
The original unix app works fine on my Mac and Linux boxes.
Does anyone know what library or compiler config I could be missing that makes this work on Windows?
UPDATE:
I did the following things to get OpenCV running:
Downloaded the binaries for v2.2 from the OpenCV site for windows. I'm using 2.2 because the original app uses it and I don't want to complicate my build at this stage.
I am trying to imwrite to a .png file. I looked at the OpenCV code and noticed the necessity for external libs for Encoders such as Pngs or jpegs, so I tried writing to .ppm, .bmp which seems not to require deps, but I get the identical error.
An example of my usage is cv::imwrite("out.png", cv_scaled); where cv_scaled is of type cv::Mat with format CV_32FC1
Please remember the identical code works fine in unix
The fact .bmp or .ppm doesn't work this raises more questions:
Why don't these very simple formats work?
Is there a way to see a list of installed Encoders programmatically?
Thanks again for your kind assistance in helping me debug this problem.
Your current installation of OpenCV doesn't support the file format you are trying to create on disk.
Check if the extension of the file is right. If it is, you'll have to recompile OpenCV and add support to this format and possibly install the libraries you are missing.
That's all that can be said without more information.
EDIT:
As I have also failed building an application that uses the C++ interface of OpenCV (v2.3 on VS2005) I ended up using the following workaround: convert the C++ types to the C types when necessary.
To convert from IplImage* to cv::Mat is pretty straight forward:
IplImage* ipl_img = cvLoadImage("test.jpg", CV_LOAD_IMAGE_UNCHANGED);
Mat mat_img(ipl_img);
imshow("window", mat_img);
The conversion cv::Mat to IplImage* is not so obvious, but it's also simple, and the trick is to use a IplImage instead of a IplImage*:
IplImage ipl_from_mat((IplImage)mat_img);
cvNamedWindow("window", CV_WINDOW_AUTOSIZE);
// and then pass the memory address of the variable when you need it as IplImage*
cvShowImage("window", &ipl_from_mat);
Try
cvSaveImage("test.jpg", &(IplImage(image)));
instead of
imwrite("test.jpg", image);
This is a known bug in the version you are using.
From the OpenCV 2.2 API:
The function imwrite saves the image to the specified file. The image format is chosen based on the filename extension, see imread for the list of extensions. Only 8-bit (or 16-bit in the case of PNG, JPEG 2000 and TIFF) single-channel or 3-channel (with ‘BGR’ channel order) images can be saved using this function. If the format, depth or channel order is different, use Mat::convertTo , and cvtColor to convert it before saving, or use the universal XML I/O functions to save the image to XML or YAML format.
You might have more luck converting your file to 8 or 16 bits before saving.
However, even with single channel 8 bit files I have had unknown extension errors trying to save jpg or png files but found that bmp works.