libqrencode二维码编译使用及BMP保存缩放转换

交叉编译

./configure --prefix=$(pwd)/_install --host=arm-rockchip-linux-gnueabihf CC=arm-rockchip-linux-gnueabihf-gcc --enable-static

C++生成二维码并保存图片

QImage QrcodeEn::encodeImage(const QString& qrTxt, int bulk,const QString& saveName)
{
    qDebug() << "QrcodeEn encodeImage";
    QImage ret;
    QRcode* qr = QRcode_encodeString(qrTxt.toUtf8(), 12, QR_ECLEVEL_Q, QR_MODE_8, 1);
    if ( qr != nullptr )
    {
        int allBulk = (qr->width) * bulk;
        ret = QImage(allBulk, allBulk, QImage::Format_MonoLSB);
        QPainter painter(&ret);
        QColor fg("black");
        QColor bg("white");
        painter.setBrush(bg);
        painter.setPen(Qt::NoPen);
        painter.drawRect(0, 0, allBulk, allBulk);

        painter.setBrush(fg);
        for( int y=0; y<qr->width; y++ )
        {
            for( int x=0; x<qr->width; x++ )
            {
                if ( qr->data[y*qr->width+x] & 1 )
                {
                    QRectF r(x*bulk, y*bulk, bulk, bulk);
                    painter.drawRects(&r, 1);
                }
            }
        }
        QRcode_free(qr);
        if(saveName!="")
            ret.save(saveName);
    }
    return ret;
}

C语言生成二维码

int qrencodeString(char *QRTEXT)
{
    QRcode *qrCode = NULL;
    int version = 12; //设置版本号,这里设为5,对应尺寸:37 * 37
    QRecLevel level = QR_ECLEVEL_Q;
    QRencodeMode hint = QR_MODE_8;
    int casesensitive = 1;
    qrCode = QRcode_encodeString(QRTEXT, version, level, hint, casesensitive);
    if (NULL == qrCode)
    {
        printf("QRcode create fail\n");
        return -1;
    }

    printf("QRcode create success\n");

    // saveQrcode("./qrcode16.bmp", qrCode, 16);
    saveQrcode("qrcode24.bmp", qrCode, 24);
    QRcode_free(qrCode);
    // resizeBmp("qrcode16.bmp", "qrcode16bit.bmp", 4);
    resizeBmp("qrcode24.bmp", "qrcode24bit.bmp", 4);
    // rgb888to565("qrcode24.bmp", "qrcode565.bmp", 16);
    
    return 0;
}

保存二维码

int saveQrcode(const char *qrcodeName, QRcode *qrCode, const unsigned char bmpBitCount)
{
    int width = qrCode->width;
    int height = qrCode->width;
    int widthByte = (width * bmpBitCount / 8 + 3) / 4 * 4; //每line字节数必须为4的倍数
    int bodySize = widthByte * height;
    unsigned char bmpByteCount = bmpBitCount / 8;

    unsigned char *qrBmpData = malloc(bodySize);
    memset(qrBmpData, 255, bodySize);
    unsigned char *qrData = qrCode->data;
    int i, j, k;
    for (i = 0; i < height; i++)
    {
        for (j = 0; j < width; j++)
        {
            if (*(qrData)&1)
            {
                //设置rgb颜色,可自定义设置,这里设为黑色。
                for (k = 0; k < bmpByteCount; ++k)
                {
                    *(qrBmpData + widthByte * i + bmpByteCount * j + k) = 0;
                }
            }
            qrData++;
        }
    }

    saveBitmap(qrcodeName, qrBmpData, width, -height, bodySize, bmpBitCount);
    free(qrBmpData);

    return 0;
}

保存BMP图片

int saveBitmap(const char *bmpName, void *bmpData, int width, int height, int bodySize, const unsigned char bmpBitCount)
{
    FILE *pf = fopen(bmpName, "wb");

    if (NULL == pf)
    {
        printf("%s file open fail.\n", bmpName);
        goto fail;
    }

    //位图文件头
    BITMAPFILEHEADER bitMapFileHeader;

    bitMapFileHeader.bfType = 0x4D42;
    bitMapFileHeader.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + bodySize;
    bitMapFileHeader.bfReserved1 = 0;
    bitMapFileHeader.bfReserved2 = 0;
    bitMapFileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);

    //位图信息头
    BITMAPINFOHEADER bitMapInfoHeader;

    bitMapInfoHeader.biSize = sizeof(BITMAPINFOHEADER);
    bitMapInfoHeader.biWidth = width;
    bitMapInfoHeader.biHeight = height; //调整BMP方向
    bitMapInfoHeader.biPlanes = 1;
    bitMapInfoHeader.biBitCount = bmpBitCount;
    bitMapInfoHeader.biCompression = 0;
    bitMapInfoHeader.biSizeImage = bodySize;
    bitMapInfoHeader.biXPelsPerMeter = 0;
    bitMapInfoHeader.biYPelsPerMeter = 0;
    bitMapInfoHeader.biClrUsed = 0;
    bitMapInfoHeader.biClrImportant = 0;

    //写文件头进文件
    if (fwrite(&bitMapFileHeader, sizeof(BITMAPFILEHEADER), 1, pf) != 1)
    {
        printf("fwrite bitMapFileHeader fail.\n");
        goto fail;
    }
    //写位图信息头进文件
    if (fwrite(&bitMapInfoHeader, sizeof(BITMAPINFOHEADER), 1, pf) != 1)
    {
        printf("fwrite bitMapInfoHeader fail.\n");
        goto fail;
    }

    //写数据进文件
    if (fwrite(bmpData, bodySize, 1, pf) != 1)
    {
        printf("fwrite bmpData fail.\n");
        goto fail;
    }

    fclose(pf);

    return 0;
fail:
    fclose(pf);
    return -1;
}

读取BMP图片

void *readBitmap(const char *bmpName, BITMAPFILEHEADER *bmpHeader, BITMAPINFOHEADER *bmpInfoHeader, int *bodySize)
{
    FILE *fd = fopen(bmpName, "rb");
    if (NULL == fd)
    {
        printf("file open fail.\n");
        fclose(fd);
        return NULL;
    }

    if (fread(bmpHeader, 1, sizeof(BITMAPFILEHEADER), fd) != sizeof(BITMAPFILEHEADER))
    {
        printf("fread fail.\n");
        return NULL;
    }

    if (fread(bmpInfoHeader, 1, sizeof(BITMAPINFOHEADER), fd) != sizeof(BITMAPINFOHEADER))
    {
        printf("fread fail.\n");
        return NULL;
    }

    *bodySize = bmpHeader->bfSize - 54;
    void *body = malloc(*bodySize);

    fseek(fd, 54, SEEK_SET);
    if (fread(body, 1, *bodySize, fd) != *bodySize)
    {
        printf("fread fail.\n");
        return NULL;
    }

    fclose(fd);
    return body;
}

缩放BMP图片

int resizeBmp(const char *srcBmpName, const char *dstBmpName, const unsigned char multiple)
{
    BITMAPFILEHEADER srcBmpHeader;
    BITMAPINFOHEADER srcBmpInfoHeader;

    unsigned char *srcBmpData = NULL;
    int srcBodySize = 0;
    srcBmpData = readBitmap(srcBmpName, &srcBmpHeader, &srcBmpInfoHeader, &srcBodySize);
    if (srcBmpData == NULL)
    {
        printf("readBitmap fail\n");
        return -1;
    }

    unsigned char bmpByteCount = srcBmpInfoHeader.biBitCount / 8;
    int srcWidthByte = (srcBmpInfoHeader.biWidth * bmpByteCount + 3) / 4 * 4;

    //  ----------------------------------
    int width = srcBmpInfoHeader.biWidth * multiple;
    int height = srcBmpInfoHeader.biHeight * multiple;
    int dstWidthSize = (width * srcBmpInfoHeader.biBitCount / 8 + 3) / 4 * 4;
    int dstBodySize = dstWidthSize * abs(height);

    unsigned char *dstBmpData = malloc(dstBodySize);
    if (dstBmpData == NULL)
    {
        printf("resizeBmp malloc error:%d\n",dstBodySize);
        free(srcBmpData);
        return -1;
    }
    memset(dstBmpData, 0, dstBodySize);
    printf("resizeBmp end\n");
    double rateH = (double)1 / multiple;
    double rateW = (double)1 / multiple;

    int tSrcH, tSrcW;
    int i, j;

    for (i = 0; i < abs(height); i++)
    {
        tSrcH = (int)(rateH * i);
        for (j = 0; j < width; j++)
        {
            tSrcW = (int)(rateW * j);
            memcpy(&dstBmpData[i * dstWidthSize] + j * bmpByteCount, &srcBmpData[tSrcH * srcWidthByte] + tSrcW * bmpByteCount, bmpByteCount);
        }
    }

    saveBitmap(dstBmpName, dstBmpData, width, height, dstBodySize, srcBmpInfoHeader.biBitCount);
    free(dstBmpData);
    free(srcBmpData);
    return 0;
}

BMP RGB888toRGB565

unsigned short RGB888toRGB565(unsigned char red, unsigned char green, unsigned char blue)
{
    // unsigned short B = (blue >> 3) & 0x001F;
    // unsigned short G = ((green >> 2) << 5) & 0x07E0;
    // unsigned short R = ((red >> 3) << 11) & 0xF800;
    unsigned short B = ((blue >> 3) & 0x1F) << 0;
    unsigned short G = ((green >> 2) & 0x3F) << 5;
    unsigned short R = ((red >> 3) & 0x1F) << 11;
    return (unsigned short)(R | G | B);
}

int rgb888to565(const char *srcBmpName, const char *dstBmpName, const unsigned char dstBitCount)
{
    BITMAPFILEHEADER srcBmpHeader;
    BITMAPINFOHEADER srcBmpInfoHeader;

    unsigned char *srcBmpData = NULL;
    int srcBodySize = 0;
    srcBmpData = readBitmap(srcBmpName, &srcBmpHeader, &srcBmpInfoHeader, &srcBodySize);
    if (srcBmpData == NULL)
    {
        printf("readBitmap fail\n");
        return -1;
    }
    int srcWidthByte = (srcBmpInfoHeader.biWidth * srcBmpInfoHeader.biBitCount / 8 + 3) / 4 * 4;
    unsigned char srcBmpByteCount = srcBmpInfoHeader.biBitCount / 8;
    //  ----------------------------------
    int width = srcBmpInfoHeader.biWidth;
    int height = srcBmpInfoHeader.biHeight;
    int widthByte = (width * dstBitCount / 8 + 3) / 4 * 4; //每line字节数必须为4的倍数
    int bodySize = widthByte * height;
    unsigned char bmpByteCount = dstBitCount / 8;

    unsigned char *dstBmpData = malloc(bodySize);

    int i, j;
    unsigned short color;
    for (i = 0; i < height; i++)
    {
        for (j = 0; j < width; j++)
        {
            color = RGB888toRGB565(srcBmpData[i * srcWidthByte + j * srcBmpByteCount + 2], srcBmpData[i * srcWidthByte + j * srcBmpByteCount + 1],
                                   srcBmpData[i * srcWidthByte + j * srcBmpByteCount]);
            dstBmpData[i * widthByte + bmpByteCount * j] = color;
            dstBmpData[i * widthByte + bmpByteCount * j + 1] = color >> 8;
        }
    }
    saveBitmap(dstBmpName, dstBmpData, width, height, bodySize, dstBitCount);
    free(dstBmpData);
    free(srcBmpData);
    return 0;
}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
libqrencode是一个C语言编写的,用于生成二维条形码。生成的二维码可以通过手机的CCD摄像机轻松扫描出来。该具有很强的鲁棒性,可以生成容量多达7000个数字或4000个字符的二维码。\[1\] 要使用libqrencode生成二维码,你需要以下几个步骤: 1. 下载稳定版本的libqrencode源代码包,可以从http://fukuchi.org/works/qrencode/下载。 2. 解压下载的源代码包,将其中的.h和.c文件拷贝到一个文件夹中,例如命名为libqrencode。 3. 创建一个工程,选择适合你的平台(如OSX或iOS)的应用程序模板。 4. 将libqrencode文件夹中的源代码添加到你的工程中。 5. 根据你的需求,调用libqrencode提供的函数来生成二维码。 这样,你就可以使用libqrencode来生成二维码了。请注意,具体的实现细节可能因你的开发环境和需求而有所不同。\[2\]\[3\] #### 引用[.reference_title] - *1* *3* [基于libqrencode二维码生成](https://blog.csdn.net/SkyNullCode/article/details/49934699)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [使用libqrencode生成二维码,支持telphone,短信,url等](https://blog.csdn.net/u013295518/article/details/89680310)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小小分享

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值