То, что мне нужно сделать, очень просто: мне нужно построить вектор с помощью CIMG, а затем сохранить график в формате jpg и добавить jpg в документ PDF с помощью JAGPDF. Чтобы сохранить CIMG в формате JPG, программа использует внешнюю программу под названием Image Magick.
Я хотел избежать использования этой программы и использовать GDI+ вместо этого сначала сохраните CIMG как BMP (он делает это изначально), а затем сохраните jpg из bmp.
Программа MCVE выглядит так
#include "CImg.h"
#include <jagpdf/api.h>
#include <vector>
using namespace jag;
using namespace cimg_library;
int main(int argc, char** const argv)
{
const float x0 = 0;
const float x1 = 9;
const int resolution = 5000;
// Create plot data.
CImg<double> values(1, resolution, 1, 1, 0);
const unsigned int r = resolution - 1;
for (int i1 = 0; i1 < resolution; ++i1)
{
double xtime = x0 + i1*(x1 - x0) / r;
values(0, i1) = 2 * sin(xtime);
}
CImg<unsigned char> graph;
graph.assign(750, 240, 1, 3, 255);
static const unsigned char black[] = { 0, 0, 0 }, white[] = { 255, 255, 255 };
static const unsigned char red[] = { 255, 200, 200 }, bred[] = { 255, 0, 0 };
graph.draw_grid(6, 6, 0, 0, false, true, red, 10.0f, 0xFFFFFFFF, 0xFFFFFFFF);
graph.draw_grid(30, 30, 0, 0, false, true, bred, 10.0f, 0xFFFFFFFF, 0xFFFFFFFF);
graph.draw_graph(values, black, 1, 1, 1, 2, -2, 0xFFFFFFFF);;
//////////////Method 1: Using Image Magick////////////////
graph.save_jpeg("plot2.jpg");
pdf::Document doc(pdf::create_file("report.pdf"));
doc.page_start(848.68, 597.6);
pdf::Image imag2 = doc.image_load_file("plot2.jpg");
doc.page().canvas().image(imag2, 50, 50);
doc.page_end();
doc.finalize();
//////////////Method 2: Using GDI+////////////////
graph.save("plot.bmp");
SaveFile();
pdf::Document doc2(pdf::create_file("report2.pdf"));
doc2.page_start(848.68, 597.6);
pdf::Image imag = doc2.image_load_file("plot.jpg");
doc2.page().canvas().image(imag, 50, 50);
doc2.page_end();
doc2.finalize();
return 0;
}
С SaveFile(), являющимся следующей функцией, использующей GDI+ для преобразования из plot.bmp в plot.jpg
#include <windows.h>
#include <objidl.h>
#include <gdiplus.h>
#include "GdiplusHelperFunctions.h"
#pragma comment (lib,"Gdiplus.lib")
VOID SaveFile()
{
// Initialize GDI+.
Gdiplus::GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
CLSID encoderClsid;
Status stat;
Image* image = new Gdiplus::Image(L"plot.bmp");
// Get the CLSID of the PNG encoder.
GetEncoderClsid(L"image/jpeg", &encoderClsid);
stat = image->Save(L"plot.jpg", &encoderClsid, NULL);
if (stat == Ok)
printf("plot.jpg was saved successfully\n");
else
printf("Failure: stat = %d\n", stat);
delete image;
GdiplusShutdown(gdiplusToken);
}
Оба метода сохраняют jpg, которые в свойствах имеют одинаковый размер, но первый правильно помещает изображение в pdf, а второй помещает огромное изображение в pdf, даже если они должны быть одинакового размера. Как я могу это исправить?
Прикрепил скриншоты report1 и report2
РЕШЕНИЕ
С вашими предложениями я смог изменить функцию SaveFile, чтобы иметь возможность контролировать DPI, я публикую новый код на случай, если он кому-то понадобится.
VOID SaveFile()
{
// Initialize GDI+.
Gdiplus::GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
CLSID encoderClsid;
Status stat;
EncoderParameters encoderParameters;
ULONG quality;
Gdiplus::Bitmap* bitmap = new Gdiplus::Bitmap(L"plot.bmp");
Gdiplus::REAL dpi = 96;
bitmap->SetResolution(dpi,dpi);
// Get the CLSID of the PNG encoder.
GetEncoderClsid(L"image/jpeg", &encoderClsid);
encoderParameters.Count = 1;
encoderParameters.Parameter[0].Guid = EncoderQuality;
encoderParameters.Parameter[0].Type = EncoderParameterValueTypeLong;
encoderParameters.Parameter[0].NumberOfValues = 1;
quality = 100;
encoderParameters.Parameter[0].Value = &quality;
stat = bitmap->Save(L"plot.jpg", &encoderClsid, &encoderParameters);
if (stat == Ok)
printf("plot.jpg was saved successfully\n");
else
printf("Failure: stat = %d\n", stat);
delete bitmap;
GdiplusShutdown(gdiplusToken);
return;
}