C++实现图片jpg格式变成16位565bmp格式

 更新时间:2025年03月06日 09:31:46   作者:万能的小裴同学  
这篇文章主要为大家详细介绍了C++如何实现图片jpg格式变成16位565bmp格式,文中的示例代码讲解详细,感兴趣的小伙伴可以了解一下

C++ 将jpg图片变成16位565bmp图片

// ConsoleApplication1.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#include<string>
#include <atlimage.h>

bool ConvertJpgTo16BitBmp565(const char* input_path, const char* output_path) {
    CImage srcImage, dstImage;

    // 1. 加载源图像
    srcImage.Load(input_path);

    int width = srcImage.GetWidth();
    int height = srcImage.GetHeight();
    int srcBpp = srcImage.GetBPP();
    int srcPitch = srcImage.GetPitch();
    BYTE* srcBits = static_cast<BYTE*>(srcImage.GetBits());

    // 2. 创建目标图像(负高度表示自上而下存储)
    DWORD masks[] = { 0xF800, 0x07E0, 0x001F };
    dstImage.CreateEx(width, height, 16, BI_BITFIELDS, masks);

    // 3. 获取目标图像参数(实际步长由API返回)
    int dstPitch = dstImage.GetPitch();
    BYTE* dstBits = static_cast<BYTE*>(dstImage.GetBits());
    // 5. 处理像素数据(无需反转行顺序)
    for (int y = 0; y < height; ++y) {
        BYTE* srcRow = srcBits + y * srcPitch;
        BYTE* dstRow = dstBits + y * dstPitch;

        for (int x = 0; x < width; ++x) {
            BYTE r, g, b;

            // 解析源像素颜色
            if (srcBpp == 24) { // 24位BGR
                BYTE* p = srcRow + x * 3;
                b = p[0];
                g = p[1];
                r = p[2];
            }
            else if (srcBpp == 32) { // 32位BGRX
                BYTE* p = srcRow + x * 4;
                b = p[0];
                g = p[1];
                r = p[2];
            }
            else {
                return false;
            }

            // 转换为RGB565
            WORD rgb565 = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);
            // 安全写入目标像素
            dstRow[x * 2] = static_cast<BYTE>(rgb565 & 0xFF);       // 低位字节
            dstRow[x * 2 + 1] = static_cast<BYTE>((rgb565 >> 8)); // 高位字节
        }
    }
    dstImage.Save(output_path, Gdiplus::ImageFormatBMP);
    return true;
}
int main()
{
    if (__argc < 2)
        return 0;
    for (int i = 1; i < __argc; i++)
    {
        std::string h = __argv[i];
        if (strcmp(h.substr(h.length() - 3).c_str(), "jpg"))
            continue;
        h=h.substr(0, h.length() - 3);
        h += "bmp";
        printf(h.c_str());
        ConvertJpgTo16BitBmp565(__argv[i], h.c_str());
    }
    return 0;
}

特殊情况使用这个,这个的效果是将图片的前8位和后8位进行对调

#include <iostream>
#include<string>
#include <atlimage.h>

bool ConvertJpgTo16BitBmp565(const char* input_path, const char* output_path) {
    CImage srcImage, dstImage;

    // 1. 加载源图像
    srcImage.Load(input_path);

    int width = srcImage.GetWidth();
    int height = srcImage.GetHeight();
    int srcBpp = srcImage.GetBPP();
    int srcPitch = srcImage.GetPitch();
    BYTE* srcBits = static_cast<BYTE*>(srcImage.GetBits());

    // 2. 创建目标图像(负高度表示自上而下存储)
    DWORD masks[] = { 0xF800, 0x07E0, 0x001F };
    dstImage.CreateEx(width, height, 16, BI_BITFIELDS, masks);

    // 3. 获取目标图像参数(实际步长由API返回)
    int dstPitch = dstImage.GetPitch();
    BYTE* dstBits = static_cast<BYTE*>(dstImage.GetBits());
    // 5. 处理像素数据(无需反转行顺序)
    for (int y = 0; y < height; ++y) {
        BYTE* srcRow = srcBits + y * srcPitch;
        BYTE* dstRow = dstBits + y * dstPitch;

        for (int x = 0; x < width; ++x) {
            BYTE r, g, b;

            // 解析源像素颜色
            if (srcBpp == 24) { // 24位BGR
                BYTE* p = srcRow + x * 3;
                b = p[0];
                g = p[1];
                r = p[2];
            }
            else if (srcBpp == 32) { // 32位BGRX
                BYTE* p = srcRow + x * 4;
                b = p[0];
                g = p[1];
                r = p[2];
            }
            else {
                return false;
            }

            // 转换为RGB565
            WORD rgb565 = ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);
            // 安全写入目标像素
            dstRow[x * 2] = static_cast<BYTE>((rgb565 >> 8));      // 低位字节
            dstRow[x * 2 + 1] = static_cast<BYTE>(rgb565 & 0xFF); // 高位字节
        }
    }
    dstImage.Save(output_path, Gdiplus::ImageFormatBMP);
    return true;
}
int main()
{
    if (__argc < 2)
        return 0;
    for (int i = 1; i < __argc; i++)
    {
        std::string h = __argv[i];
        if (strcmp(h.substr(h.length() - 3).c_str(), "jpg"))
            continue;
        h=h.substr(0, h.length() - 3);
        h += "bmp";
        printf(h.c_str());
        ConvertJpgTo16BitBmp565(__argv[i], h.c_str());
    }
    return 0;
}

方法补充

下面小编为大家整理了C++实现图片转换不同格式的方法,需要的可以了解下

#include <opencv2/opencv.hpp>
#include <iostream>
 
int main() {
    // 输入文件路径和输出文件路径
    std::string inputImagePath, outputImagePath;
    
    std::cout << "Enter the input image file path: ";
    std::cin >> inputImagePath;
    
    std::cout << "Enter the output image file path (e.g., output.png, output.jpg): ";
    std::cin >> outputImagePath;
 
    // 读取图片
    cv::Mat image = cv::imread(inputImagePath, cv::IMREAD_UNCHANGED);
 
    // 检查图片是否成功加载
    if (image.empty()) {
        std::cerr << "Error: Could not open or find the image!" << std::endl;
        return -1;
    }
 
    // 保存图片到新格式
    bool success = cv::imwrite(outputImagePath, image);
 
    if (success) {
        std::cout << "Image successfully converted and saved to " << outputImagePath << std::endl;
    } else {
        std::cerr << "Error: Could not save the image!" << std::endl;
    }
 
    return 0;
}

到此这篇关于C++实现图片jpg格式变成16位565bmp格式的文章就介绍到这了,更多相关C++图片jpg转bmp内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C/C++模拟实现烟花效果的示例代码

    C/C++模拟实现烟花效果的示例代码

    这篇文章主要为大家详细介绍了C/C++模拟实现烟花效果的两种简单方法,文中的示例代码讲解详细,具有一定的借鉴价值,感兴趣的小伙伴可以了解下
    2024-01-01
  • C语言中字符串与各数值类型之间的转换方法

    C语言中字符串与各数值类型之间的转换方法

    这篇文章主要介绍了C语言中字符串与各数值类型之间的转换方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-03-03
  • 深入uCOS中全局变量的使用详解

    深入uCOS中全局变量的使用详解

    本篇文章是对uCOS中全局变量的使用进行了详细的分析介绍,需要的朋友参考下
    2013-05-05
  • C++堆排序算法实例详解

    C++堆排序算法实例详解

    这篇文章主要介绍了C++堆排序算法,简单分析了堆排序算法的原理并结合实例形式分析了C++实现堆排序的具体操作技巧,需要的朋友可以参考下
    2017-08-08
  • 探讨:C++实现链式二叉树(用非递归方式先序,中序,后序遍历二叉树)

    探讨:C++实现链式二叉树(用非递归方式先序,中序,后序遍历二叉树)

    本篇文章是对用C++实现链式二叉树(用非递归方式先序,中序,后序遍历二叉树)的方法进行了详细的分析介绍,需要的朋友参考下
    2013-05-05
  • 详解C语言之实现通讯录

    详解C语言之实现通讯录

    这篇文章主要为大家详细介绍了用C语言实现通讯录,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-11-11
  • C++内存泄漏的检测与实现详细流程

    C++内存泄漏的检测与实现详细流程

    内存泄漏(memory leak) 是指由于疏忽或错误造成了程序未能释放掉不再使用的内存的情况。内存泄漏并非指内存在物理上的消失,而是应用程序分配某段内存后,由于设计错误,失去了对该段内存的控制,因而造成了内存的浪费
    2022-08-08
  • C++继承介绍

    C++继承介绍

    C++继承可以是单一继承或多重继承,每一个继承连接可以是public,protected,private也可以是virtual或non-virtual
    2013-01-01
  • C++二叉树的创建及遍历详情

    C++二叉树的创建及遍历详情

    这篇文章主要介绍了C++二叉树的创建及遍历详情,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下,希望对你的学习有所帮助
    2022-07-07
  • C++中的强制类型转换操作详解

    C++中的强制类型转换操作详解

    C++中提供了四种强制类型转换技术:static_cast、dynamic_cast、reinterpret_cast和const_cast。这些技术能够在需要时将一种类型转换为另一种类型,但需要注意它们的适用条件和安全性。程序员需要根据具体情况选择合适的强制类型转换方式,以确保程序的正确性和可靠性
    2023-04-04

最新评论