How to Create a Bitmap Programmatically? - winapi

I'd like to create programmatically a random X height and Y width bitmap file.
The content, for me, is irrelevant. It could be all white, empty. What is important is the dimension.
How to do it using Windows API?

You wish to create a Bitmap File using the windows API? There is no specific helper for this. a BMP file however is very simple:
Write out a BITMAPFILEHEADER struct.
Write out a BITMAPINFO struct.
Write out an array of bytes, enough to hold the format and dimensions described in the BITMAPINFO struct.
The MSDN has an Article with sample code demonstrating how.

I suppose you have Microsoft .NET 2.0 Framework installed. (1.1 is also usable).
Using Notepad, create test.cs file with this code:
namespace test
{
class Program
{
static void Main(string[] args)
{
if (args.Length == 3)
new System.Drawing.Bitmap(System.Convert.ToInt32(args[0]), System.Convert.ToInt32(args[1]))
.Save(args[2] + ".bmp", System.Drawing.Imaging.ImageFormat.Bmp);
else
System.Console.WriteLine("Usage: test.exe 100 200 filename");
}
}
}
Then create test.cmd file with this code:
#echo off
%windir%\Microsoft.NET\Framework\v2.0.50727\csc.exe /t:exe test.cs
Execute test.cmd
Execute text.exe

In .Net you can just new up a Bitmap object:
Image myImage = new Bitmap(width, height);

GDI+ includes commands to load/save BMP images in C++. This sample code shows how to load and save images: Converting a BMP Image to a PNG Image. The Bitmap class also has a ctor that takes a width, a height and a pixel format to create empty images.

If you really insist on making an image with windows API,you should use Gdi32.dll
In C# just call
Import dll file into your assembly, so you can use external methods in
DllImport["Gdi32.dll"]
HBITMAP CreateCompatibleBitmap(
HDC hdc,
int nWidth,
int nHeight
);
Then call Bitmap class from this Bitmap like
Bitmap bmp = Bitmap.FromHbitmap( nameOfBitmap );
bmp.Save("C:\NewImage.jpg");
There is an example in msdn page here

Related

Create a font resource from byte array on Win32

I have a byte array that contains the contents of a read in font file. I'd like WinAPI (No Gdi+) to create a font resource from it, so I could use it for rendering text.
I only know about AddFontResourceExW, that loads in a font resource from file, and AddFontMemResourceEx, which sounded like what I'd need, but it seems to me that it's still some resource-system thing and the data would have to be pre-associated with the program.
Can I somehow convert my loaded in byte-array into a font resource? (Possibly without writing it to a file and then calling AddFontResourceExW)
When you load a font from a resource script into memory, you use code like the following (you didn't add a language tag, so I'm using C/C++ code - let me know if that's a problem):
HANDLE H_myfont = INVALID_HANDLE_VALUE;
HINSTANCE hResInstance = ::GetModuleHandle(nullptr);
HRSRC ares = FindResource(hResInstance, MAKEINTRESOURCE(IDF_MYID), L"BINARY");
if (ares) {
HGLOBAL amem = LoadResource(hResInstance, ares);
if (amem != nullptr) {
void *adata = LockResource(amem);
DWORD nFonts = 0, len = SizeofResource(hResInstance, ares);
H_myfont = AddFontMemResourceEx(adata, len, nullptr, &nFonts);
}
}
The key line here is void *adata = LockResource(amem); - this converts the font resource loaded as an HGLOBAL into 'accessible memory' (documentation). Now, assuming your byte array is in the correct format (see below), you could probably just pass a pointer to it (as void*) in the call to AddFontMemResourceEx. (You can use your known array size in place of calling SizeofResource.)
I would suggest code something like this:
void *my_font_data = (void*)(font_byte_array); // Your byte array data
DWORD nFonts = 0, len = sizeof(font_byte_array);
H_myfont = AddFontMemResourceEx(my_font_data, len, nullptr, &nFonts);
which (hopefully) will give you a loaded and useable font resource.
When you're done with the font (which, once loaded, can be used just like any system-installed font), you can release it with:
RemoveFontMemResourceEx(H_myfont);
As I don't have your byte array, I can't (obviously) test this idea. However, if you do try it, please let us know if it works. (If it doesn't, there may be some other, relatively straightforward, steps that need to be added.)
NOTE: Although I can't say 100% what the exact format expected of a "font resource" is, the fact that code given above works (for me) with a resource defined in the .rc script as a BINARY with a normal, ".ttf" file, suggests that, if your byte array follows the format of a Windows Font File, then it should work. This is how I have included a font as an embedded resource:
IDF_MYFONT BINARY L"..\\Resource\\MyFont.ttf"

How do I copy DirectX texture to a surface?

I'm trying to capture whole desktop screen (front buffer) and add a logo and caption to each frame.
I load the logo (.png or .jpeg file) as IDirect3DTexture9 and I try to add it to a IDirect3DSurface9 image frame (screenshot).
As I'm new to DirecX9, I have no idea how to copy the logo (texture) to the screenshot (surface/buffer). Any help would be appreciated.
(If there's any other way to add logo to each frame without involving texture, please do tell me.)
EDIT:
I have used the code suggested in an answer below. The hr result returned is an error.
IDirect3DSurface9 *pSurface = NULL;
pDevice->GetFrontBufferData(0, pSurface); //my screenshot
LPDIRECT3DTEXTURE9 tex = NULL; //my logo
//[code to load logo from file here]
IDirect3DSurface9 *pSurf = NULL;
tex->GetSurfaceLevel(0, &pSurf);
hr = pDevice->StretchRect(pSurf, NULL, pSurface, NULL, D3DTEXF_NONE); //HR GIVES AN ERROR
You can use StretchRect.
The code will look something like this (pseudo):
ID3DSurface9 *pScreenSurface = ... // your screenshot surface should be created in default pool and the same format as your texture(see bellow), like this:
CreateOffscreenPlainSurface(width, height, D3DFMT_X8B8G8R8, D3DPOOL_DEFAULT, &pScreenSurface, NULL);
// Now get a screenshot by using either GetFrontBufferData, or GetBackBuffer/GetRenderTargetData by supplying pScreenSurface as a parameter (not shown here).
ID3DTexture9 *pTexture = ... // your texture should be loaded in default pool and the same format as your screenshot surface, like this:
D3DXCreateTextureFromFileEx(*ppDevice, L"icon.bmp", 40, 40, D3DX_DEFAULT, 0,
D3DFMT_X8B8G8R8, D3DPOOL_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL,
NULL, &pTexture);
ID3DSurface9 *pSurf;
pTexture->GetSurfaceLevel(0, &pSurf); // don't forget to Release pSurf after StretchRect
RECT rc = { ... initialize the destination rectangle here };
pDevice->StretchRect(pSurf, NULL, pScreenSurface, &rc);
You need to specify a destination rectangle inside the destination surface, where you want your texture to be copied.

BOOL CImageList::Replace( int nImage, CBitmap* pbmImage, CBitmap* pbmMask )

I have an imagelist.
For some operations I am extracting toolbar images and replacing the image in the imagelist using
BOOL CImageList::Replace( int nImage, CBitmap* pbmImage, CBitmap* pbmMask );
I need to apply mask color RGB(255,0,255) while replacing.
ICONINFO iconinfo;
GetIconInfo(hIcon, &iconinfo);
HBITMAP hBitmap = iconinfo.hbmColor;
m_imgListSingle.Replace(0,CBitmap::FromHandle(hBitmap),???)
I dont know what I need to pass for third argument for CImageList Replace function.
There is no way to use the Replace function with a mask color directly.
You may succeed in using the following sequence:
Use the CImageList::Add method with the appropriate mask color
Use CImageList::GetImageInfo to extract the bitmaps that got created by the Add command
Use the CImageList::Replace method with the extracted bitmaps
use the CImageList::Delete method to delete the newly created image.
Dont't forget to free the bitmaps you retrieved by CImageList::GetImageInfo

Save high quality images from Autocad

my problem is that I don´t have much experience with Autocad. Thus I don´t know how to save a project in a good quality image (png?) to insert in a latex document.
Could you give me a hint?
Thank you
Autocad's Publish to Web printers are pretty bad. What I would do is print using DWG to PDF printer or similar (there are a few in autocad's default printer list) then convert that pdf to raster images using a second software like Photoshop, GIMP, etc. There are even small software that convert pdf's to jpgs like TTRPDFToJPG3. If you have a specific idea of what kind of output you're looking for, please feel free to elaborate further. cheers!
If you're looking for a programmatic way to capture the screen, here it is:
using acApp = Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.Runtime;
using System.Drawing.Imaging;
using System.Drawing;
namespace ScreenshotTest
{
public class Commands
{
[CommandMethod("CSS")]
static public void CaptureScreenShot()
{
ScreenShotToFile(
acApp.Application.MainWindow,
"c:\\main-window.png",
0, 0, 0, 0
);
ScreenShotToFile(
acApp.Application.DocumentManager.MdiActiveDocument.Window,
"c:\\doc-window.png",
30, 26, 10, 10
);
}
private static void ScreenShotToFile(
Autodesk.AutoCAD.Windows.Window wd,
string filename,
int top, int bottom, int left, int right
)
{
Point pt = wd.Location;
Size sz = wd.Size;
pt.X += left;
pt.Y += top;
sz.Height -= top + bottom;
sz.Width -= left + right;
// Set the bitmap object to the size of the screen
Bitmap bmp =
new Bitmap(
sz.Width,
sz.Height,
PixelFormat.Format32bppArgb
);
using (bmp)
{
// Create a graphics object from the bitmap
using (Graphics gfx = Graphics.FromImage(bmp))
{
// Take a screenshot of our window
gfx.CopyFromScreen(
pt.X, pt.Y, 0,0, sz,
CopyPixelOperation.SourceCopy
);
// Save the screenshot to the specified location
bmp.Save(filename, ImageFormat.Png);
}
}
}
}
}
Source: Taking screenshots of AutoCAD’s main and drawing windows using .NET
Thanks to everyone. I am saving the files in pdf and after I´m using GIMP to convert them in PNG.

load a ttf font with the Windows API

With CreateFont one can specify font name and a bunch of other properties. However, what if I have a font.ttf file, and I want that particular font to be loaded by windows? How do I specify that specific file to be used?
I'm pretty sure you can't. All requests for fonts go through the font mapper, and it picks out the font file that comes the closest to meeting the specifications you've given. Though I'm not sure it even does in reality, it could at least theoretically use (for example) data from two entirely separate font files to create one logical font.
It's admittedly rather indirect, but you could utilize GDI interop with DWrite when running on Windows 7+.
#include <Windows.h>
#include <WindowsX.h>
#include <DWrite.h>
...
// Make the font file visible to GDI.
AddFontResourceEx(fontFileName, FR_PRIVATE, 0);
if (SUCCEEDED(GetLogFontFromFileName(fontFileName, &logFont)))
{
logFont.lfHeight = -long(desiredPpem);
HFONT hf = CreateFontIndirect(&logFont);
HFONT oldFont = SelectFont(hdc, hf);
...
// Do stuff...
...
SelectFont(hdc, oldFont);
}
RemoveFontResource(fontFileName);
....
HRESULT GetLogFontFromFileName(_In_z_ wchar const* fontFileName, _Out_ LOGFONT* logFont)
{
// DWrite objects
ComPtr<IDWriteFactory> dwriteFactory;
ComPtr<IDWriteFontFace> fontFace;
ComPtr<IDWriteFontFile> fontFile;
ComPtr<IDWriteGdiInterop> gdiInterop;
// Set up our DWrite factory and interop interface.
IFR(DWriteCreateFactory(
DWRITE_FACTORY_TYPE_SHARED,
__uuidof(IDWriteFactory),
reinterpret_cast<IUnknown**>(&dwriteFactory)
);
IFR(g_dwriteFactory->GetGdiInterop(&gdiInterop));
// Open the file and determine the font type.
IFR(g_dwriteFactory->CreateFontFileReference(fontFileName, nullptr, &fontFile));
BOOL isSupportedFontType = false;
DWRITE_FONT_FILE_TYPE fontFileType;
DWRITE_FONT_FACE_TYPE fontFaceType;
UINT32 numberOfFaces = 0;
IFR(fontFile->Analyze(&isSupportedFontType, &fontFileType, &fontFaceType, &numberOfFaces));
if (!isSupportedFontType)
return DWRITE_E_FILEFORMAT;
// Set up a font face from the array of font files (just one)
ComPtr<IDWriteFontFile> fontFileArray[] = {fontFile};
IFR(g_dwriteFactory->CreateFontFace(
fontFaceType,
ARRAYSIZE(fontFileArray), // file count
&fontFileArray[0], // or GetAddressOf if WRL ComPtr
0, // faceIndex
DWRITE_FONT_SIMULATIONS_NONE,
&fontFace
);
// Get the necessary logical font information.
IFR(gdiInterop->ConvertFontFaceToLOGFONT(fontFace, OUT logFont));
return S_OK;
}
Where IFR is just a failure macro that returns on a FAILED HRESULT, and ComPtr is a helper smart pointer class (substitute with your own, or ATL CComPtr, WinRT ComPtr, VS2013 _com_ptr_t...).
One possibility is to EnumFonts(), save the results. Then add your private font with AddFontResourceEx(), and EnumFonts() again, the difference is what you added. Note that TTF and bitmap fonts enumerate differently, but for this test, that shouldn't matter.
If you were using bitmap fonts, they could be easily parsed (.FNT and .FON). TTF you'd likely have to build (or borrow, as another commenter suggested FreeType) a parser to pull the "name" table out of the TTF file.
That seems like a lot of work for a font you're controlling or supplying with your app.
We use AddFontResourceEx() to add a private font, but since we control the font we're adding, we just hardcode the fontname passed to CreateFontIndirect() to match.
If you dont care about installing the font you can do so with AddFontResource then you can fetch the relationship between the physical .TTF and it logical/family name by looking at the mappings in HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts.
I mentioned PrivateFontCollection in my comment because I thought you wanted to do this temporarily; you can load a TTF into a PFC with PrivateFontCollection::AddFontFile, fetch back the new FontFamily object from the collection & examime GetFamilyName. (I've done similar with the .net implementation of this but not the raw API)

Resources