これは、GoogleのPDFIUMライブラリを使用してPDFを読み込む方法です。私はvoid*
を受け取る:メモリへのポインタを保持できません
doc = FPDF_LoadDocument("media1.pdf", NULL);
は、今私は基本的に私は上記のコードから戻って受信void*
あるFPDF_DOCUMENT
のベクトルでこの文書を保存したいです。私はベクトルでそれを保存していますどのようにこれは、次のとおりです。
pdfs.push_back(doc);
問題は、私は、このメソッドのスコープ外に行うとき、私はdoc
によって指さそのメモリへのアクセスを持っていけないです。私は、docが範囲外になったとき、GCがそのメモリを解放すると思います。このValgridデバッグツールについて知っておく必要があります。 docはpdfを読み込むコマンドと同じ機能で宣言されています。
私は基本的には読み込まれたpdfを保持して、後でそのページにアクセスしてページをレンダリングできるようにしたいと思います。
Valgrindの出力:
==4816== 64 bytes in 1 blocks are definitely lost in loss record 175 of 616
==4816== at 0x4C2A105: operator new(unsigned long) (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==4816== by 0x85175B: FPDFBitmap_Create (in /home/ec2-user/Vid/dist/Debug/GNU-MacOSX/video_creator_mount)
==4816== by 0x4586A1: Blrt::PDFManager::RenderPDFPage(int, int) (PDFManager.cc:159)
後はPDFManager方法である:
std::unique_ptr<Canvas::LoadedPDFInfo> PDFManager::LoadPDF(const std::vector<uint8_t>& data, size_t dataSize)
{
if(!initPDFIUM) {
InitPDFIUM();
currentPDFHandle = 0;
}
FPDF_DOCUMENT doc;
// doc = FPDF_LoadMemDocument(&data[0], dataSize, nullptr);
doc = FPDF_LoadDocument("media1.pdf", NULL);
if (!doc) {
unsigned long err = FPDF_GetLastError();
fprintf(stderr, "Load pdf docs unsuccessful: ");
switch (err) {
case FPDF_ERR_SUCCESS:
fprintf(stderr, "Success");
break;
case FPDF_ERR_UNKNOWN:
fprintf(stderr, "Unknown error");
break;
case FPDF_ERR_FILE:
fprintf(stderr, "File not found or could not be opened");
break;
case FPDF_ERR_FORMAT:
fprintf(stderr, "File not in PDF format or corrupted");
break;
case FPDF_ERR_PASSWORD:
fprintf(stderr, "Password required or incorrect password");
break;
case FPDF_ERR_SECURITY:
fprintf(stderr, "Unsupported security scheme");
break;
case FPDF_ERR_PAGE:
fprintf(stderr, "Page not found or content error");
break;
default:
fprintf(stderr, "Unknown error %ld", err);
}
fprintf(stderr, ".\n");
return nullptr;
}
pdfs.push_back(doc);
//doc = nullptr;
std::unique_ptr<Canvas::LoadedPDFInfo> pdfInfo(new Canvas::LoadedPDFInfo);
pdfInfo->handle = ++currentPDFHandle;
pdfInfo->totalPageNum = FPDF_GetPageCount(doc);
std::cout << "ERROR\n";
return pdfInfo;
}
PDFファイルがPDFManager.hで宣言さベクターである:
namespace Blrt
{
class PDFManager
{
public:
static std::unique_ptr<Canvas::LoadedPDFInfo> LoadPDF(const std::vector<uint8_t>& data, size_t dataSize);
static std::unique_ptr<Canvas::TextureData> RenderPDFPage(int32_t pdfHandle, int32_t pageNum);
static void Dispose();
private:
static void InitPDFIUM();
static void UnsupportedHandler(UNSUPPORT_INFO*, int type);
static bool initPDFIUM;
static int32_t currentPDFHandle;
static std::vector<FPDF_DOCUMENT> pdfs;
static int32_t nextMultipleOf4(size_t num);
};
}
後は、ここでの方法の一部であります私は上記の方法を使用してロードされたpdfデータにアクセスするためにpdfsにアクセスしています:
std::unique_ptr<Canvas::TextureData> PDFManager::RenderPDFPage(int32_t pdfHandle, int32_t pageNum)
{
if (pdfs[pdfHandle-1]) {
auto pdf = *(pdfs[pdfHandle-1]);
std::cout << pdfHandle << " " << pageNum << " " <<pdfs.size() << "\n";
if (1 <= pageNum && pageNum <= FPDF_GetPageCount(pdf)) {
auto page = FPDF_LoadPage(pdf, pageNum);
if(page) {
auto textPage = FPDFText_LoadPage(page);
if (textPage) {
auto scale = 2.0;
auto maxTexSize = VideoCreator::VideoCreator::MaxTextureSize;
auto orgWidth = FPDF_GetPageWidth(page);
auto orgHeight = FPDF_GetPageHeight(page);
auto targetWidth = orgWidth * scale;
auto targetHeight = orgHeight * scale;
if (targetWidth > targetHeight) {
if (targetWidth > maxTexSize) {
scale = maxTexSize/targetWidth;
}
} else {
if (targetHeight > maxTexSize) {
scale = maxTexSize/targetHeight;
}
}
もう少しコードを共有できますか? pdfsオブジェクトはどこにありますか? – DaveyLaser
C++にgcがありません – Incomputable
@laser_wizard今あなたの提案は何ですか? – asad