#include <gdiplus.h>
using namespace Gdiplus;
#pragma comment (lib,"Gdiplus.lib")
then draw some text:
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
HDC hdc;
Font *fn = new Font(TEXT("Arial"),50);
hdc=GetDC(hWnd);
ColorBlend cb = new ColorBlend();
LinearGradientBrush *linGrBrush=new LinearGradientBrush(
Point(0, 10),
Point(200, 10),
Color(255, 255, 0, 0),
Color(255, 0, 0, 255));
Graphics *graphics=new Graphics(hdc);
PointF drawPoint = PointF(150.0F,150.0F);
SolidBrush* myBrush = new SolidBrush(Color::Black);
graphics->DrawString(L"Test text",strlen("Test text"),fn,drawPoint,linGrBrush);
GdiplusShutdown(gdiplusToken);
And had error that ColorBlend not found identifier,but seem all right. How I can fix it?
The ColorBlend class is part of the .Net Framework, as far as I can tell there is nothing by that name in GDI+ for C++.
I think the corresponding function in GDI+ is LinearGradientBrush::SetInterpolationColors
As far as I understand the .NET documentation the InterpolationColors member in GDI+ is used here with this function.
Related
I wrote a program to save a BMP of a Greek word.
Here it is:
#include <Windows.h>
#include <gdiplus.h>
#include <iostream>
#pragma comment(lib,"gdiplus.lib")
using namespace Gdiplus;
using namespace std;
int main()
{
// Initialize GDI+.
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
{
// Create a bitmap.
Bitmap bmp(500, 500, PixelFormat24bppRGB);
Graphics graphics(&bmp);
// Set the font.
FontFamily fontFamily(L"Arial");
Font font(&fontFamily, 36, FontStyleRegular, UnitPixel);
graphics.SetTextRenderingHint(TextRenderingHintAntiAlias);
graphics.SetSmoothingMode(SmoothingModeHighQuality);
// Draw the text.
SolidBrush brush(Color(255, 0, 0, 0));
WCHAR text[] = L"ΔΙΔΑΣΚΑΛΙΑ";
PointF origin(100.0f, 100.0f);
graphics.DrawString(text, -1, &font, origin, &brush);
// Save the bitmap.
Status test = bmp.Save(L"greek_word.bmp", &ImageFormatBMP);
printf("%d", test);
}
// Clean up GDI+.
GdiplusShutdown(gdiplusToken);
return 0;
}
For some reason, it creates the BMP, but it has a file size of 0.
And, for some reason, bmp.Save returns a FileNotFound error.
Anyone know why I am getting this strange behavior?
Thanks.
I'm using the GDI+ API just to display an image (bmp) on the screen. Here is the code of the function doing the task:
void drawImg_ArmorInfo_PupupWnd(HDC hdc) {
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
Image* image = new Image(L"C:/Users/Darek/F2 stuff/art/intrface/armor_info_1.bmp");
int a1 = image->GetWidth();
int a2 = image->GetHeight();
Graphics graphics(hdc);
graphics.DrawImage(image, 0, 0);
delete image;
GdiplusShutdown(gdiplusToken);
}
The problem is that I'm getting an exception: Access violation writing location 0xXXXXXXXX after calling the GdiplusShutdown function. What's interesting when I comment out the
Graphics graphics(hdc);
graphics.DrawImage(image, 0, 0);
part the program runs without any problems but, of course, the image isn't drawn. When I comment out the call to GdiplusShutdown function - no problems again.
What's wrong with the code and what can be the reason of the problem here?
graphics falls out of the scope after the GdiplusShutdown so it cannot destruct correctly.
Try this:
Graphics * graphics = new Graphics(hdc);
graphics->DrawImage(image, 0, 0);
delete graphics;
I'm using the GDI+ API just to display an image (bmp) on the screen. Here is the code of the function doing the task:
void drawImg_ArmorInfo_PupupWnd(HDC hdc) {
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
Image* image = new Image(L"C:/Users/Darek/F2 stuff/art/intrface/armor_info_1.bmp");
int a1 = image->GetWidth();
int a2 = image->GetHeight();
Graphics graphics(hdc);
graphics.DrawImage(image, 0, 0);
delete image;
GdiplusShutdown(gdiplusToken);
}
The problem is that I'm getting an exception: Access violation writing location 0xXXXXXXXX after calling the GdiplusShutdown function. What's interesting when I comment out the
Graphics graphics(hdc);
graphics.DrawImage(image, 0, 0);
part the program runs without any problems but, of course, the image isn't drawn. When I comment out the call to GdiplusShutdown function - no problems again.
What's wrong with the code and what can be the reason of the problem here?
graphics falls out of the scope after the GdiplusShutdown so it cannot destruct correctly.
Try this:
Graphics * graphics = new Graphics(hdc);
graphics->DrawImage(image, 0, 0);
delete graphics;
When saving a bitmap file from a GDI+ metafile object, the output is affected by the current display scale of the monitor.
For example, the following code sample generates these images:
with screen at 100% scaling (81x81 pixel bitmap generated).
with screen at 125% scaling (52x52 pixel bitmap generated).
#include <Windows.h>
// GDI+ libraries
#include <gdiplus.h>
#pragma comment(lib, "gdiplus.lib")
void main()
{
// Startup GDI+
ULONG_PTR gdiplusToken;
Gdiplus::GdiplusStartupInput gdiplusStartupInput;
Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, nullptr);
{
// Create a metafile
const auto dc = GetDC(nullptr);
const auto cdc = CreateCompatibleDC(dc);
Gdiplus::Metafile metafile{ L"test.emf", cdc };
auto graphics = Gdiplus::Graphics::FromImage(&metafile);
// Draw some things
Gdiplus::SolidBrush yellowBrush{ Gdiplus::Color::Yellow };
graphics->FillRectangle(&yellowBrush, 0, 0, 70, 70);
Gdiplus::SolidBrush redBrush(Gdiplus::Color::Red);
graphics->FillRectangle(&redBrush, 10, 10, 50, 50);
delete graphics; // Must be deleted before saving (is this the correct way?)
// Save as BMP (MIME type: image/bmp)
CLSID bmpEncoderId{1434252288, 6660, 4563, {154, 115, 0, 0, 248, 30, 243, 46}};
auto status = metafile.Save(L"test.bmp", &bmpEncoderId);
// Cleanup
DeleteDC(cdc);
ReleaseDC(nullptr, dc);
}
// Shutdown GDI+
Gdiplus::GdiplusShutdown(gdiplusToken);
}
I've tried adding the following in several places (as suggested in other SO answers) but this doesn't seem to change the behviour.
// Set scaling
Gdiplus::MetafileHeader mfh{};
metafile.GetMetafileHeader(&mfh);
graphics->ScaleTransform(mfh.GetDpiX() / graphics->GetDpiX(),
mfh.GetDpiY() / graphics->GetDpiY());
Is it possible to export the full bitmap image independent of what scaling is set on the monitor?
SOLUTION: This was caused by not compiling as DPI-aware.
I am trying to use GDI+ to draw text onto an image, however, I notice that with DrawString(...) there is my text, followed by several misc characters (it looks like maybe Japanese). These characters only show up when using DrawString, and I notice by saving the Bitmap to a file. Does anyone know what may be causing this? My GDI Code is
#include <windows.h>
#include <Gdiplus.h>
using namespace Gdiplus;
int main(void)
{
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
Font* myFont = new Font(L"Times New Roman", 10);
Bitmap* characterBitmap = new Bitmap(256, 256, PixelFormat32bppARGB);
Graphics* g = new Graphics(characterBitmap);
g->Clear(Color::Transparent);
SolidBrush* myBrush = new SolidBrush(Color::Black);
g->DrawString(L"TEST", 48, myFont, PointF(0, 0), myBrush);
CLSID pngClsid;
GetEncoderClsid(L"image/png", &pngClsid);
characterBitmap->Save(L"test.png", &pngClsid, NULL);
GdiplusShutdown(gdiplusToken);
return 0;
}
You should read the documentation of the Graphics::DrawString function.
The second parameter should be:
Integer that specifies the number of characters in the string array. The length parameter can be set to –1 if the string is null terminated.