IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 交叉编译mupdf 在ARM板上读取pdf -> 正文阅读

[嵌入式]交叉编译mupdf 在ARM板上读取pdf

基于imx6的muPdf交叉编译连接 : https://blog.csdn.net/yinshengbing2010/article/details/91038095
? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
移植连接 : https://www.cnblogs.com/pang1567/p/4083740.html
例子 :? https://www.cnblogs.com/blueroses/p/8268217.html
? ? ? ? ? ? ? https://blog.csdn.net/k_wang_/article/details/82870401? ? // 这个例子改吧改吧好使
交叉工具链路径 :
? CC = /home/arm-20210720/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc
? CXX = /home/arm-20210720/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-g++
? LD = /home/arm-20210720/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc
? AR = /home/arm-20210720/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-ar
移植过程 :( 注意版本?)
1. 使用的 mupdf-1.15.0-source.tar.gz? 版本, 下载地址 :? https://www.mupdf.com/downloads/index.html?

2. 源码包到Ubuntu 下解压 :? 进入源码路径? mupdf-1.15.0-source 中? 修改编译依赖的文件?Makerules 修改:

# Configuration for the Makefile

OS := $(shell uname)
OS := $(OS:MINGW%=MINGW)
OS := $(OS:MSYS%=MINGW)
OS := $(OS:Windows_NT=MINGW)
OS := $(OS:Darwin=MACOS)

ifeq ($(findstring -fembed-bitcode,$(XCFLAGS)),)
? # clang does not support these in combination with -fembed-bitcode
? CFLAGS += -ffunction-sections -fdata-sections
endif

ifeq ($(OS),MACOS)
? LDREMOVEUNREACH := -Wl,-dead_strip
else
? LDREMOVEUNREACH := -Wl,--gc-sections
endif

SANITIZE_FLAGS += -fsanitize=address
SANITIZE_FLAGS += -fsanitize=leak

ifeq ($(build),debug)
? CFLAGS += -pipe -g
? LDFLAGS += -g
else ifeq ($(build),release)
? CFLAGS += -pipe -O2 -DNDEBUG -fomit-frame-pointer
? LDFLAGS += $(LDREMOVEUNREACH) -Wl,-s
else ifeq ($(build),small)
? CFLAGS += -pipe -Os -DNDEBUG -fomit-frame-pointer
? LDFLAGS += $(LDREMOVEUNREACH) -Wl,-s
else ifeq ($(build),valgrind)
? CFLAGS += -pipe -O2 -DNDEBUG -DPACIFY_VALGRIND -fno-omit-frame-pointer
? LDFLAGS += $(LDREMOVEUNREACH) -Wl,-s
else ifeq ($(build),sanitize)
? CFLAGS += -pipe -g -fno-omit-frame-pointer $(SANITIZE_FLAGS)
? LDFLAGS += -g $(SANITIZE_FLAGS)
else ifeq ($(build),sanitize-release)
? CFLAGS += -pipe -O2 -DNDEBUG -fno-omit-frame-pointer $(SANITIZE_FLAGS)
? LDFLAGS += $(LDREMOVEUNREACH) -Wl,-s $(SANITIZE_FLAGS)
else ifeq ($(build),profile)
? CFLAGS += -pipe -O2 -DNDEBUG -pg
? LDFLAGS += -pg
else ifeq ($(build),coverage)
? CFLAGS += -pipe -g -pg -fprofile-arcs -ftest-coverage
? LIBS += -lgcov
else ifeq ($(build),native)
? CFLAGS += -pipe -O2 -DNDEBUG -fomit-frame-pointer -march=native
? LDFLAGS += $(LDREMOVEUNREACH) -Wl,-s
else ifeq ($(build),memento)
? CFLAGS += -pipe -g -DMEMENTO
? LDFLAGS += -g -d -rdynamic
? ifneq ($(HAVE_LIBDL),no)
? ? CFLAGS += -DHAVE_LIBDL
? ? LIBS += -ldl
? endif
else ifeq ($(build),gperf)
? CFLAGS += -pipe -O2 -DNDEBUG -fomit-frame-pointer -DGPERF
? LIBS += -lprofiler
else
? $(error unknown build setting: '$(build)')
endif

# Default system libraries
SYS_FREETYPE_LIBS := -lfreetype2
SYS_HARFBUZZ_LIBS := -lharfbuzz
SYS_JBIG2DEC_LIBS := -ljbig2dec
SYS_JPEGXR_LIBS := -ljpegxr
SYS_LCMS2_LIBS := -llcms2-art
SYS_LIBJPEG_LIBS := -ljpeg
SYS_MUJS_LIBS := -lmujs
SYS_OPENJPEG_LIBS := -lopenjp2
SYS_ZLIB_LIBS := -lz

ifeq ($(OS),MINGW)
? WINDRES := windres
? HAVE_WIN32 := yes

else ifeq ($(OS),MACOS)
? HAVE_GLUT := yes
? SYS_GLUT_CFLAGS := -Wno-deprecated-declarations
? SYS_GLUT_LIBS := -framework GLUT -framework OpenGL
? CC = xcrun cc
? AR = xcrun ar
? LD = xcrun ld
? RANLIB = xcrun ranlib

else ifeq ($(OS),Linux)
? HAVE_OBJCOPY := yes

? ifeq ($(shell pkg-config --exists freetype2 && echo yes),yes)
?? ?SYS_FREETYPE_CFLAGS := $(shell pkg-config --cflags freetype2)
?? ?SYS_FREETYPE_LIBS := $(shell pkg-config --libs freetype2)
? endif
? ifeq ($(shell pkg-config --exists harfbuzz && echo yes),yes)
?? ?SYS_HARFBUZZ_CFLAGS := $(shell pkg-config --cflags harfbuzz)
?? ?SYS_HARFBUZZ_LIBS := $(shell pkg-config --libs harfbuzz)
? endif
? ifeq ($(shell pkg-config --exists lcms2 && echo yes),yes)
?? ?SYS_LCMS2_CFLAGS := $(shell pkg-config --cflags lcms2)
?? ?SYS_LCMS2_LIBS := $(shell pkg-config --libs lcms2)
? endif
? ifeq ($(shell pkg-config --exists libjpeg && echo yes),yes)
?? ?SYS_LIBJPEG_CFLAGS := $(shell pkg-config --cflags libjpeg)
?? ?SYS_LIBJPEG_LIBS := $(shell pkg-config --libs libjpeg)
? endif
? ifeq ($(shell pkg-config --exists libopenjp2 && echo yes),yes)
?? ?SYS_OPENJPEG_CFLAGS := $(shell pkg-config --cflags libopenjp2)
?? ?SYS_OPENJPEG_LIBS := $(shell pkg-config --libs libopenjp2)
? endif
? ifeq ($(shell pkg-config --exists zlib && echo yes),yes)
?? ?SYS_ZLIB_CFLAGS := $(shell pkg-config --cflags zlib)
?? ?SYS_ZLIB_LIBS := $(shell pkg-config --libs zlib)
? endif

? HAVE_GLUT := yes
? ifeq ($(HAVE_GLUT),yes)
?? ?SYS_GLUT_CFLAGS :=
?? ?SYS_GLUT_LIBS := -lglut -lGL
? endif

? HAVE_X11 := $(shell pkg-config --exists x11 xext && echo yes)
? ifeq ($(HAVE_X11),yes)
?? ?X11_CFLAGS := $(shell pkg-config --cflags x11 xext)
?? ?X11_LIBS := $(shell pkg-config --libs x11 xext)
? endif

? HAVE_LIBCRYPTO := $(shell pkg-config --exists 'libcrypto >= 1.1.0' && echo yes)
? ifeq ($(HAVE_LIBCRYPTO),yes)
?? ?LIBCRYPTO_CFLAGS := $(shell pkg-config --cflags libcrypto) -DHAVE_LIBCRYPTO
?? ?LIBCRYPTO_LIBS := $(shell pkg-config --libs libcrypto)
? endif

? HAVE_PTHREAD := yes
? ifeq ($(HAVE_PTHREAD),yes)
?? ?PTHREAD_CFLAGS :=
?? ?PTHREAD_LIBS := -lpthread
? endif

endif

# The following section has various cross compilation configurations.
#
# Invoke these as:
# ? ? ?make OS=mingw32-cross
#
# This does rely on the generated directory being populated with the font files.
# On a unix-like system, run 'make generate' before doing the cross compile.
# On Windows, run 'nmake -f scripts\fontdump.nmake' in a Visual Studio command prompt.

# 文件原始内容,改为自己arm平台依赖的交叉工具
ifeq "$(OS)" "wasm"
??OUT := build/wasm/$(build)
??CC = emcc
??CXX = em++
??HAVE_GLUT=no
??HAVE_X11=no
??HAVE_OBJCOPY=no
??HAVE_LIBCRYPTO=no
endif

# 修改后的内容

ifeq "$(OS)" "arm-linux"
? OUT := build/arm-linux/$(build)
? CC = /home/arm-20210720/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc
? CXX = /home/arm-20210720/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-g++
? LD = /home/arm-20210720/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc
? AR = /home/arm-20210720/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-ar

? HAVE_GLUT=no
? HAVE_X11=no
? HAVE_OBJCOPY=no
? HAVE_LIBCRYPTO=no
? CROSSCOMPILE=yes
? HAVE_GLUT:=no
endif

ifeq "$(OS)" "mingw32-cross"
? OUT := build/$(OS)/$(build)
? CC = i686-w64-mingw32-gcc
? CXX = i686-w64-mingw32-g++
? LD = i686-w64-mingw32-gcc
? AR = i686-w64-mingw32-ar
? WINDRES = i686-w64-mingw32-windres
? HAVE_WIN32=yes
endif

ifeq "$(OS)" "mingw64-cross"
? OUT := build/$(OS)/$(build)
? CC = x86_64-w64-mingw32-gcc
? CXX = x86_64-w64-mingw32-g++
? LD = x86_64-w64-mingw32-gcc
? AR = x86_64-w64-mingw32-ar
? WINDRES = x86_64-w64-mingw32-windres
? HAVE_WIN32=yes
endif

# Most variables when building for iOS are set up in ios/build_libs.sh,
# which is called from the Xcode project as a "Run Script" build step.
# The following section works for both device and simulator builds.
ifeq "$(OS)" "ios"
? CC = xcrun cc
? CXX = xcrun c++
? AR = xcrun ar
? LD = xcrun ld
? RANLIB = xcrun ranlib
endif
?

3.修改完编译依赖的文件后开始编译前 : 先在源码路径下创建 build 文件?

?? ??? ?? ? 1). 根据 Makerules 文件提示首先执行? :?make generate? 在源码路径下生成?generated 目录

?2).? 执行make编译? :make OS=arm-linux? build=release? ?OS 指定使用哪个配置编译,build指定在源码路径下build 生成 编译后的文件,最后未报错,则编译成功,报错,从头再来

期间试了好几个版本没有成功,最终使用的是 这个?mupdf-1.15.0? ? 最终在源码路径下的build 下生成静态库:

因为在 make 的时候指定的是 “arm-linux” 选项的编译所以生成的对应的是此选项的库

4.编译完源码移植到QT 中使用?

?? ??? ?? ? 1)。首先创建一个空的工程,然后把生成的四个静态库引入 :[【?libmupdf.a? ?libmupdf-pkcs7.a? ??libmupdf-third.a? ??libmupdf-threads.a? 】

?? ??? ?? ? 2)。在源码路径下的include 目录下存在着需要引用的头文件,把整个文件夹拷贝到工程目录下

? 3)?工程中使用

5.一个简单的基于QT 的例子:自定义封装一个类

在工程文件 .pro 中引入静态库,此处我给的是绝对路径,然后就可以使用了

需要修改头文件路径到自己工程指定的路径下:

?pdfreader.cpp 文件:

#include "pdfreader.h"

PdfReader::PdfReader(QWidget *parent,QString path) :QWidget(parent)
{
    this->grabKeyboard();
    this->resize(1024,600);
    this->setAttribute(Qt::WA_DeleteOnClose,true); // 设置窗体关闭释放申请的空间属性

    mainWidget = new QWidget(this);
    mainWidget->resize(1024,600);
    mainWidget->move(0,0);
    mainWidget->setStyleSheet("background:rgb(213,205,169);");

    this->filePath = path;
// -------------------------------->
    pageNum=0;//第一页为0
    zoom=1; //100%缩放比
    rotate=0;//旋转为0

    //创建上下文
    ctx = fz_new_context(NULL, NULL, FZ_STORE_UNLIMITED);
    if (!ctx)
    {
#if PDF_READER_DEBUG
        qDebug()  << __FILE__ << __FUNCTION__ << "Line Num : " << __LINE__ << stderr<<"cannot create mupdf context";
#endif
        return;
    }

    //注册文档控制
    fz_try(ctx)
       fz_register_document_handlers(ctx);
    fz_catch(ctx)
    {
#if PDF_READER_DEBUG
       qDebug() << __FILE__ << __FUNCTION__ << "Line Num : " << __LINE__ <<stderr<<"cannot register document handlers:"<< fz_caught_message(ctx);
#endif
        fz_drop_context(ctx);
        return;
    }

    char *temp = NULL;
    if(filePath.isEmpty() == false)
    {
        QByteArray byteArray = filePath.toLocal8Bit();
        temp = byteArray.data();
    }
    if(temp == NULL)
    {
        qWarning() << __FILE__ << __FUNCTION__ << "Line Num : " << __LINE__  << " file name is null ";
        return;
    }

    //打开文档
    fz_try(ctx)
        doc = fz_open_document(ctx, temp); // Boost程序库完全开发指南深入C++准标准库.pdf
    fz_catch(ctx)
    {
#if PDF_READER_DEBUG
        qDebug() << __FILE__ << __FUNCTION__ << "Line Num : " << __LINE__ << stderr<< "cannot open document:"<< fz_caught_message(ctx);
#endif
        fz_drop_context(ctx);
        return;
    }

    //取得总的页数
    fz_try(ctx)
       pageCnt = fz_count_pages(ctx, doc);
    fz_catch(ctx)
    {
#if PDF_READER_DEBUG
       qDebug() << __FILE__ << __FUNCTION__ << "Line Num : " << __LINE__  <<stderr<< "cannot count number of pages:"<< fz_caught_message(ctx);
#endif
       fz_drop_document(ctx, doc);
       fz_drop_context(ctx);
       return;
    }
#if PDF_READER_DEBUG
    qDebug() << __FILE__ << __FUNCTION__ << "Line Num : " << __LINE__ << "pageCnt: "<< pageCnt;
#endif

    //get outline
    fz_outline *outline = fz_load_outline(ctx, (fz_document*)doc);
    fz_try(ctx)
       fz_print_outline(ctx, fz_stderr(ctx), outline, 0);
    fz_always(ctx)
       fz_drop_outline(ctx, outline);
    fz_catch(ctx)
       fz_rethrow(ctx);

//
    LogoArea = new QScrollArea(mainWidget);
    LogoArea->setGeometry(0, 0, 1024-80, 600);
    LogoArea->move(80,0);
    LogoArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
    LogoArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    pdfLabel=new QLabel(mainWidget);
    pdfLabel->setVisible(false);
    LogoArea->setWidget(pdfLabel);
    LogoArea->setAlignment(Qt::AlignCenter);

    QStringList barQss ;
    barQss.append("QScrollBar:vertical {border:0px solid rgb(237,237,237);background:rgb(255,237,237);width:3px; margin-top:0px;margin-bottom:0px;}");
    barQss.append("QScrollBar::handle:vertical {background:rgb(255,0,0);border-radius:6px;min-height:80px;}");  // 滑块设置
    barQss.append("QScrollBar::sub-line:vertical{height:0px;subcontrol-position:top;subcontrol-origin:margin;}");
    barQss.append("QScrollBar::add-line:vertical{height:0px;subcontrol-position:bottom;subcontrol-origin:margin;}");
    LogoArea->verticalScrollBar()->setStyleSheet(barQss.join(""));
//    LogoArea->horizontalScrollBar()->setStyleSheet(barQss.join(""));

    pageInfoLabel = new QLabel(this);
    pageInfoLabel->resize(80,40);
    pageInfoLabel->move(0,10);
    pageInfoLabel->setStyleSheet("background:rgb(255,255,255);");
    pageInfoLabel->setAlignment(Qt::AlignCenter);

    QStringList btnQss ;
    btnQss.append(QString("QPushButton{outline:none;border-style:solid;border-color:#035593;border-radius:5px;color:#000000;background:rgb(208,208,208);}"));
    btnQss.append(QString("QPushButton:pressed{color:#A0DAFB;background:rgb(133,133,133);}"));
    QPushButton* zoomInBtn = new QPushButton(this);
    zoomInBtn->setText("放大");
    zoomInBtn->resize(80,50);
    zoomInBtn->move(0,120);
    zoomInBtn->setStyleSheet(btnQss.join(""));
    connect( zoomInBtn, SIGNAL(released()), this, SLOT(zoom_in_btn_handler()));

    QPushButton* zoomOutBtn = new QPushButton(this);
    zoomOutBtn->setText("缩小");
    zoomOutBtn->resize(80,50);
    zoomOutBtn->move(0,180);
    zoomOutBtn->setStyleSheet(btnQss.join(""));
    connect( zoomOutBtn, SIGNAL(released()), this, SLOT(zoom_out_btn_handler()));

    QPushButton* prevBtn = new QPushButton(this);
    prevBtn->setText("上一页");
    prevBtn->resize(80,50);
    prevBtn->move(0,380);
    prevBtn->setStyleSheet(btnQss.join(""));
    connect(prevBtn, SIGNAL(released()), this, SLOT(previous_page_btn_handler()));

    QPushButton* nextBtn = new QPushButton(this);
    nextBtn->setText("下一页");
    nextBtn->resize(80,50);
    nextBtn->move(0,440);
    nextBtn->setStyleSheet(btnQss.join(""));
    connect( nextBtn, SIGNAL(released()), this, SLOT(next_page_btn_handler()));

    QPushButton* backBtn = new QPushButton(this);
    backBtn->setText("返回");
    backBtn->resize(80,50);
    backBtn->move(0,540);
    backBtn->setStyleSheet(btnQss.join(""));
    connect( backBtn, SIGNAL(released()), this, SLOT(back_btn_handler()));

    if (pageNum < 0 || pageNum >= pageCnt)
    {
#if PDF_READER_DEBUG
       qDebug()  << __FILE__ << __FUNCTION__ << "Line Num : " << __LINE__  << stderr << "page number out of range: "<< pageNum + 1<<"page count:"<<pageCnt;
#endif
       fz_drop_document(ctx, doc);
       fz_drop_context(ctx);
       return;
    }
    pageInfoLabel->setText( tr("%1/%2页").arg(pageNum+1).arg(pageCnt) );

    fz_matrix ctm = fz_scale( zoom, zoom);
    fz_pre_rotate(ctm, rotate);
    fz_try(ctx)
    pix = fz_new_pixmap_from_page_number(ctx, doc, pageNum, ctm, fz_device_rgb(ctx), 0);
    fz_catch(ctx)
    {
#if PDF_READER_DEBUG
        qDebug() << __FILE__ << __FUNCTION__ << "Line Num : " << __LINE__ << stderr << "cannot render page: %s\n" << fz_caught_message(ctx);
#endif
        fz_drop_document(ctx, doc);
        fz_drop_context(ctx);
        return;
    }

    unsigned char *samples = pix->samples;
    int width = fz_pixmap_width(ctx, pix);
    int height = fz_pixmap_height(ctx, pix);
#if PDF_READER_DEBUG
    qDebug() << __FILE__ << __FUNCTION__ << "Line Num : " << __LINE__  << "width: "<<width;
    qDebug() << __FILE__ << __FUNCTION__ << "Line Num : " << __LINE__  << "height: "<<height;
#endif
    pdfLabel->setGeometry(0,0,width,height);
    pdfLabel->setAlignment(Qt::AlignCenter);

    QImage image(samples, width, height,pix->stride,QImage::Format_RGB888);
    pdfLabel->setPixmap(QPixmap::fromImage(image));
    pdfLabel->setVisible(true);

    fz_drop_pixmap(ctx, pix);
    update();
}


PdfReader::~PdfReader()
{
}

// 前一页
void PdfReader::previous_page_btn_handler()
{
#if PDF_READER_DEBUG
    qDebug() << __FILE__ << __FUNCTION__ << " Line Num : " << __LINE__ << "onPrev";
#endif
    pageNum--;
    if(pageNum <= 0)
        pageNum = 0;
    pageInfoLabel->setText( tr("%1/%2页").arg(pageNum+1).arg(pageCnt) );
    update_page();
}

// 下一页
void PdfReader::next_page_btn_handler()
{
#if PDF_READER_DEBUG
    qDebug() << __FILE__ << __FUNCTION__ << " Line Num : " << __LINE__ << "onNext";
#endif
    pageNum++;
    if(pageNum >= pageCnt -1)
        pageNum = pageCnt -1;
    pageInfoLabel->setText( tr("%1/%2页").arg(pageNum+1).arg(pageCnt) );
    update_page();
}

// 放大
void PdfReader::zoom_in_btn_handler()
{
    if(zoom >= 6.5) return;
    zoom += 0.05;
#if PDF_READER_DEBUG
        qDebug() << __FILE__ << __FUNCTION__ << " Line Num : " << __LINE__ << " zoom in : " << zoom ;
#endif
    update_page();
}

// 缩小
void PdfReader::zoom_out_btn_handler()
{
    if(zoom <= 0.65) return;
    zoom -= 0.05;
#if PDF_READER_DEBUG
        qDebug() << __FILE__ << __FUNCTION__ << " Line Num : " << __LINE__ << " zoom out : " << zoom ;
#endif
    update_page();
}

void PdfReader::back_btn_handler()
{
    this->close();
}

void PdfReader::fz_print_outline(fz_context *ctx, fz_output *out, fz_outline *outline, int level)
{
    int i;
    if(outline == NULL)
    {
#if PDF_READER_DEBUG
        qDebug() << __FILE__ << __FUNCTION__ << " Line Num : " << __LINE__ << "outline is NULL!";
#endif
    }
    while (outline)
    {
        for (i = 0; i < level; i++)
        //    fz_write_printf(ctx, out, "\t");
        //fz_write_printf(ctx, out, "%s\t%s\n", outline->title, outline->uri);
        qDebug() << __FILE__ << __FUNCTION__ << " Line Num : " << __LINE__ << outline->title<<" " << outline->uri;
        if (outline->down)
            fz_print_outline(ctx, out, outline->down, level + 1);
        outline = outline->next;
    }
}


void PdfReader::update_page()
{
    fz_matrix ctm = fz_scale( zoom, zoom);
    fz_pre_rotate(ctm, rotate);
    fz_try(ctx)
        pix = fz_new_pixmap_from_page_number(ctx, doc, pageNum, ctm, fz_device_rgb(ctx), 0);
    fz_catch(ctx)
    {
#if PDF_READER_DEBUG
        qDebug()  << __FILE__ << __FUNCTION__ << " Line Num : " << __LINE__ << stderr << "cannot render page: %s\n"<< fz_caught_message(ctx);
#endif
        fz_drop_document(ctx, doc);
        fz_drop_context(ctx);
        return;
    }

    unsigned char *samples = pix->samples;
    int width = fz_pixmap_width(ctx, pix);
    int height = fz_pixmap_height(ctx, pix);

#if PDF_READER_DEBUG
    qDebug()  << __FILE__ << __FUNCTION__ << " Line Num : " << __LINE__ << "width: "<<width;
    qDebug()  << __FILE__ << __FUNCTION__ << " Line Num : " << __LINE__ << "height: "<<height;
#endif

    pdfLabel->setGeometry(0,0,width,height);
    pdfLabel->setAlignment(Qt::AlignCenter);

    QImage image(samples, width, height,pix->stride,QImage::Format_RGB888);
    pdfLabel->setPixmap(QPixmap::fromImage(image));
    pdfLabel->setVisible(true);

    fz_drop_pixmap(ctx, pix);
    update();
}

void PdfReader::keyPressEvent(QKeyEvent *e)
{
    switch (e->key())
    {
    case Qt::Key_F4: // HOME
        break;
    case Qt::Key_F5: // back
        break;
    default:
        break;
    }
    //QWidget::keyPressEvent(e);
}

void PdfReader::keyReleaseEvent(QKeyEvent *e)
{
    switch (e->key())
    {
    case Qt::Key_F4:    // HOME
        e->ignore();
        break;


    case Qt::Key_F5:    // back
        this->close();
        e->accept();
        break;


    default:
        break;
    }
    //QWidget::keyReleaseEvent(e);
}

void PdfReader::mousePressEvent(QMouseEvent* event)
{
    pressFlag = true;
    pressPoint = event->pos();
}

void PdfReader::mouseReleaseEvent(QMouseEvent* event)
{
    Q_UNUSED(event);
    pressFlag = false;
    pressPoint.setX(0);
    pressPoint.setY(0);
}

void PdfReader::mouseMoveEvent(QMouseEvent* event)      //鼠标移动函数
{
    if (pressFlag == false)
    {
        return;
    }
    QPoint curPoint = event->pos();
    int x_dist = pressPoint.x() - curPoint.x();
    int y_dist = pressPoint.y() - curPoint.y();
    LogoArea->horizontalScrollBar()->setValue(LogoArea->horizontalScrollBar()->value() + x_dist);
    LogoArea->verticalScrollBar()->setValue(LogoArea->verticalScrollBar()->value() + y_dist);
    pressPoint = curPoint;
    moveFlag = true;
}

pdfreader.h 文件 :

#ifndef PDFREADER_H
#define PDFREADER_H


#include <QWidget>
#include <QLabel>
#include <QPushButton>
#include <QImage>
#include <QDebug>
#include <QGridLayout>
#include <QVBoxLayout>
#include <QScrollArea>
#include <QKeyEvent>
#include <QMouseEvent>
#include <QScrollBar>

#include "mupdf/pdf.h"
#include "mupdf/fitz.h"

#define PDF_READER_DEBUG 1

class PdfReader : public QWidget
{
    Q_OBJECT
public:
    explicit PdfReader(QWidget *parent = 0,QString path="");
    ~PdfReader();

private:
    QWidget *mainWidget = NULL;
    QLabel *pdfLabel = NULL;   // 显示PDF内容
    QLabel *pageInfoLabel = NULL; // 显示页码
    QScrollArea *LogoArea = NULL;

    float scale = 0;
    float zoom = 0;   // 不能小于0.65, 当为负数时反向放大
    float rotate = 0; //
    int pageNum = 0;  // 当前页码(从0开始)
    int pageCnt = 0;  // 总页码

    //
    fz_context  *ctx = NULL;
    fz_document *doc = NULL;
    fz_pixmap   *pix = NULL;

    QString filePath = "";
    bool    pressFlag = false;
    bool    moveFlag = false;
    QPoint  pressPoint;
private:
    void update_page();
    void fz_print_outline(fz_context *ctx, fz_output *out, fz_outline *outline, int level);
public slots:
    void previous_page_btn_handler(); // 前一页
    void next_page_btn_handler();     // 下一页
    void zoom_in_btn_handler();       // 放大
    void zoom_out_btn_handler();      // 缩小
    void back_btn_handler();
protected:
    virtual void keyPressEvent(QKeyEvent *e);
    virtual void keyReleaseEvent(QKeyEvent *e);
    virtual void mousePressEvent(QMouseEvent* event);
    virtual void mouseReleaseEvent(QMouseEvent* event);
    virtual void mouseMoveEvent(QMouseEvent* event);

};

#endif // PDFREADER_H

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2021-07-28 07:59:49  更:2021-07-28 08:00:20 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/27 10:27:58-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计