惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
大猫的无限游戏
大猫的无限游戏
博客园 - 聂微东
Jina AI
Jina AI
The Cloudflare Blog
V
Visual Studio Blog
博客园_首页
量子位
酷 壳 – CoolShell
酷 壳 – CoolShell
博客园 - 【当耐特】
爱范儿
爱范儿
博客园 - 三生石上(FineUI控件)
小众软件
小众软件
博客园 - 司徒正美
阮一峰的网络日志
阮一峰的网络日志
Last Week in AI
Last Week in AI
V
V2EX
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - 叶小钗
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
WordPress大学
WordPress大学
宝玉的分享
宝玉的分享
T
Tailwind CSS Blog
博客园 - Franky

博客园 - 南水之源

AI助手选哪个?Cowork vs OpenClaw深度解析:程序猿、打工人、老板们看过来 "数字管家"Claude Cowork,正在接管你的桌面 Claude Code:那只被称为"代码章鱼"的AI,正在吃掉整个编程世界 “拥有数字生命的龙虾”OpenClaw的前世今生 怎么领取使用国家超算中心小龙虾tokens 使用gdal修改shp数据 保存OE中使用的高程数据用gdal保存成tif文件[完成] blender GIS介绍 使用qt读取系统字体库,并进行英文名称映射 c++开发大模型mcp服务(七)使用cpp-mcp的例子MCP-ExcelAutoCpp c++开发大模型mcp服务(六)cpp-mcp库说明 c++开发大模型mcp服务(五)编译c++版本的mcp库(cpp-mcp) c++开发大模型mcp服务(四)使用工具测试高德地图的MCP(流程验证) c++开发大模型mcp服务(三)一个常规的MCP调用例子(以高德地图MCP举例) c++开发大模型mcp服务(二)MCP 架构说明 c++开发大模型mcp服务(一)目的和概念 解除360首页锁定操作 辅助Visual Studio上C++开发的工具(插件) [书]清华大学DeepSeek:从入门到精通 [原]geoserver缓存切片类GeoServerMetaTile的解析UML
osgImage和QImage互相转换
南水之源 · 2026-05-06 · via 博客园 - 南水之源

//1 osg::Image 转 QImage

1 osg::ref_ptr<osg::Image> image = osgDB::readImageFile(......);
2 QImage img((const uchar*)image ->data(), image->s(), image->t(),
3 image->getRowSizeInBytes(),
4 QImage::Format_RGB888);

//2 QImage 转 osg::Image

#include <QImage>
 
const int GL_BGRA = 0x80E1;
const int GL_RGBA = 0x1908;
 
static inline QRgb convertToGLPixelFormat(QRgb src_pixel, GLenum texture_format)
{
    if (texture_format == GL_BGRA) {
        if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
            return ((src_pixel << 24) & 0xff000000)
                | ((src_pixel >> 24) & 0x000000ff)
                | ((src_pixel << 8) & 0x00ff0000)
                | ((src_pixel >> 8) & 0x0000ff00);
        }
        else {
            return src_pixel;
        }
    }
    else {  // GL_RGBA
        if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
            return (src_pixel << 8) | ((src_pixel >> 24) & 0xff);
        }
        else {
            return ((src_pixel << 16) & 0xff0000)
                | ((src_pixel >> 16) & 0xff)
                | (src_pixel & 0xff00ff00);
        }
    }
}
 
static void convertQImageToGLFormat(QImage &dst, const QImage &img, GLenum texture_format)
{
    if (dst.size() != img.size()) {
        int target_width = dst.width();
        int target_height = dst.height();
        qreal sx = target_width / qreal(img.width());
        qreal sy = target_height / qreal(img.height());
        quint32 *dest = (quint32 *)dst.scanLine(0); // NB! avoid detach here
        const uchar *srcPixels = img.constScanLine(img.height() - 1);
        int sbpl = img.bytesPerLine();
        int dbpl = dst.bytesPerLine();
        int ix = int(0x00010000 / sx);
        int iy = int(0x00010000 / sy);
        quint32 basex = int(0.5 * ix);
        quint32 srcy = int(0.5 * iy);
        // scale, swizzle and mirror in one loop
        while (target_height--) {
            const uint *src = (const quint32 *)(srcPixels - (srcy >> 16) * sbpl);
            int srcx = basex;
            for (int x = 0; x < target_width; ++x) {
                dest[x] = convertToGLPixelFormat(src[srcx >> 16], texture_format);
                srcx += ix;
            }
            dest = (quint32 *)(((uchar *)dest) + dbpl);
            srcy += iy;
        }
    }
    else {
        const int width = img.width();
        const int height = img.height();
        const uint *p = (const uint*)img.scanLine(img.height() - 1);
        uint *q = (uint*)dst.scanLine(0);
        if (texture_format == GL_BGRA) {
            if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
                // mirror + swizzle
                for (int i = 0; i < height; ++i) {
                    const uint *end = p + width;
                    while (p < end) {
                        *q = ((*p << 24) & 0xff000000)
                            | ((*p >> 24) & 0x000000ff)
                            | ((*p << 8) & 0x00ff0000)
                            | ((*p >> 8) & 0x0000ff00);
                        p++;
                        q++;
                    }
                    p -= 2 * width;
                }
            }
            else {
                const uint bytesPerLine = img.bytesPerLine();
                for (int i = 0; i < height; ++i) {
                    memcpy(q, p, bytesPerLine);
                    q += width;
                    p -= width;
                }
            }
        }
        else {
            if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
                for (int i = 0; i < height; ++i) {
                    const uint *end = p + width;
                    while (p < end) {
                        *q = (*p << 8) | ((*p >> 24) & 0xff);
                        p++;
                        q++;
                    }
                    p -= 2 * width;
                }
            }
            else {
                for (int i = 0; i < height; ++i) {
                    const uint *end = p + width;
                    while (p < end) {
                        *q = ((*p << 16) & 0xff0000) | ((*p >> 16) & 0xff) | (*p & 0xff00ff00);
                        p++;
                        q++;
                    }
                    p -= 2 * width;
                }
            }
        }
    }
}
 
static QImage convertToGLFormat(const QImage& img)
{
    QImage res(img.size(), QImage::Format_ARGB32);
    convertQImageToGLFormat(res, img.convertToFormat(QImage::Format_ARGB32), GL_RGBA);
    return res;
}
 

// 将QImage转为osg::Image代码调用
QImage image(.....);
auto osgimage = new osg::Image;
osgimage->setImage(
image.width(), image.height(), 1, 4, GL_RGBA, GL_UNSIGNED_BYTE, images[key].bits()
, osg::Image::NO_DELETE, 1);