JPG轻量化小记

1、缩小像素

#include <iostream>
#include <opencv2/opencv.hpp>

int main() {
    // 1. 读取图片
    cv::Mat img = cv::imread(R"(C:\Users\Administrator\Desktop\ThreeData\weixingOBJ\tex\AM84_027_Radar_Diff.jpg)");
    if (img.empty()) {
        std::cerr << "Failed to open image." << std::endl;
        return -1;
    }
    int origin_width = img.rows;
    int origin_height = img.cols;
    std::cout << "origin_width:" << origin_width << ",origin_height:" << origin_height << std::endl;

    int channels = img.channels();
    std::cout << "channels:" << channels << std::endl;
    //channels()函数会返回图像的通道数。例如,对于灰度图像,它返回1;
    // 对于BGR或RGB图像,它返回3;对于带alpha通道的图像(如RGBA或BGRA),它返回4。
    
    // 2. 修改图片的像素大小
    cv::Mat resizedImg;
    int newWidth = origin_width/2;  // 新的宽度
    int newHeight = origin_height/2; // 新的高度
    cv::resize(img, resizedImg, cv::Size(newWidth, newHeight));

    // 3. 保存图片
    if (!cv::imwrite(R"(C:\Users\Administrator\Desktop\ThreeData\weixingOBJ\tex\out.jpg)", resizedImg)) {
        std::cerr << "Failed to save image." << std::endl;
        return -1;
    }

    std::cout << "Image resizing successful!" << std::endl;
    return 0;
}

opencv读取的图像是BGR,可以用语法转换

cv::Mat rgbImg;
cv::cvtColor(bgrImg, rgbImg, cv::COLOR_BGR2RGB);

 GitHub - microsoft/DirectXTex: DirectXTex texture processing library

GitHub - nothings/stb: stb single-file public domain libraries for C/C++

在线查看 DDS 文件的免费在线工具 - ImageToStl

 主要是DirectXTex库,将jpg转换位dds。当然下面的代码兼容性极差,只可以转jpg,因为我把一些代码都删了,只保留我想测试的功能。

#include <cstring> // For memcpy
#define STB_DXT_IMPLEMENTATION
#include "stb_dxt.h"
#include <DirectXTex.h>
#include <opencv2/opencv.hpp>

//调用这个.h文件
#include "DirectXTex.h"
#include <filesystem>

#define CODEC_DDS 0xFFFF0001
#define CODEC_TGA 0xFFFF0002
#define CODEC_HDP 0xFFFF0003
#define CODEC_JXR 0xFFFF0004
#define CODEC_HDR 0xFFFF0005
#define CODEC_PPM 0xFFFF0006
#define CODEC_PFM 0xFFFF0007

enum OPTIONS : uint64_t
{
    OPT_RECURSIVE = 1,
    OPT_FILELIST,
    OPT_WIDTH,
    OPT_HEIGHT,
    OPT_MIPLEVELS,
    OPT_FORMAT,
    OPT_FILTER,
    OPT_SRGBI,
    OPT_SRGBO,
    OPT_SRGB,
    OPT_PREFIX,
    OPT_SUFFIX,
    OPT_OUTPUTDIR,
    OPT_TOLOWER,
    OPT_OVERWRITE,
    OPT_FILETYPE,
    OPT_HFLIP,
    OPT_VFLIP,
    OPT_DDS_DWORD_ALIGN,
    OPT_DDS_BAD_DXTN_TAILS,
    OPT_DDS_PERMISSIVE,
    OPT_USE_DX10,
    OPT_USE_DX9,
    OPT_TGA20,
    OPT_TGAZEROALPHA,
    OPT_WIC_QUALITY,
    OPT_WIC_LOSSLESS,
    OPT_WIC_MULTIFRAME,
    OPT_NOLOGO,
    OPT_TIMING,
    OPT_SEPALPHA,
    OPT_NO_WIC,
    OPT_TYPELESS_UNORM,
    OPT_TYPELESS_FLOAT,
    OPT_PREMUL_ALPHA,
    OPT_DEMUL_ALPHA,
    OPT_EXPAND_LUMINANCE,
    OPT_TA_WRAP,
    OPT_TA_MIRROR,
    OPT_FORCE_SINGLEPROC,
    OPT_GPU,
    OPT_NOGPU,
    OPT_FEATURE_LEVEL,
    OPT_FIT_POWEROF2,
    OPT_ALPHA_THRESHOLD,
    OPT_ALPHA_WEIGHT,
    OPT_NORMAL_MAP,
    OPT_NORMAL_MAP_AMPLITUDE,
    OPT_BC_COMPRESS,
    OPT_COLORKEY,
    OPT_TONEMAP,
    OPT_X2_BIAS,
    OPT_PRESERVE_ALPHA_COVERAGE,
    OPT_INVERT_Y,
    OPT_RECONSTRUCT_Z,
    OPT_ROTATE_COLOR,
    OPT_PAPER_WHITE_NITS,
    OPT_BCNONMULT4FIX,
    OPT_SWIZZLE,
    OPT_MAX
};
using namespace DirectX;

int main() {
    std::string imgPath = R"(C:\Users\Administrator\Desktop\ALLData\s1.jpg)";
    // Parameters and defaults
    size_t width = 0;
    size_t height = 0;
    size_t mipLevels = 0;
    DXGI_FORMAT format = DXGI_FORMAT_UNKNOWN;
    TEX_FILTER_FLAGS dwFilter = TEX_FILTER_DEFAULT;
    TEX_FILTER_FLAGS dwSRGB = TEX_FILTER_DEFAULT;
    TEX_FILTER_FLAGS dwConvert = TEX_FILTER_DEFAULT;
    TEX_COMPRESS_FLAGS dwCompress = TEX_COMPRESS_DEFAULT;
    TEX_FILTER_FLAGS dwFilterOpts = TEX_FILTER_DEFAULT;
    uint32_t FileType = CODEC_DDS;
    uint32_t maxSize = 16384;
    int adapter = -1;
    float alphaThreshold = TEX_THRESHOLD_DEFAULT;
    float alphaWeight = 1.f;
    CNMAP_FLAGS dwNormalMap = CNMAP_DEFAULT;
    float nmapAmplitude = 1.f;
    float wicQuality = -1.f;
    uint32_t colorKey = 0;
    uint32_t dwRotateColor = 0;
    float paperWhiteNits = 200.f;
    float preserveAlphaCoverageRef = 0.0f;
    bool keepRecursiveDirs = false;
    bool dxt5nm = false;
    bool dxt5rxgb = false;
    uint32_t swizzleElements[4] = { 0, 1, 2, 3 };
    uint32_t zeroElements[4] = {};
    uint32_t oneElements[4] = {};

    wchar_t szPrefix[MAX_PATH] = {};
    wchar_t szSuffix[MAX_PATH] = {};
    std::filesystem::path outputDir;


    // --- Load source image -------------------------------------------------------
    wprintf(L"reading %ls", imgPath.c_str());
    fflush(stdout);

    TexMetadata info;
    std::unique_ptr<ScratchImage> image(new (std::nothrow) ScratchImage);

    if (!image)
    {
        wprintf(L"\nERROR: Memory allocation failed\n");
        return 1;
    }
    HRESULT hr = CoInitializeEx(nullptr, COINIT_MULTITHREADED);
    WIC_FLAGS wicFlags = WIC_FLAGS_NONE | dwFilter;
    if (FileType == CODEC_DDS)
        wicFlags |= WIC_FLAGS_ALL_FRAMES;
   

    std::filesystem::path curpath(imgPath);
    auto const ext = curpath.extension();
    //轻松搞定得到image,简化版本(只处理jpg)
    hr = LoadFromWICFile(curpath.c_str(), wicFlags, &info, *image);
    if (FAILED(hr)) {
        //一系列错误
    }
    size_t tMips = (!mipLevels && info.mipLevels > 1) ? info.mipLevels : mipLevels;

    if (IsPlanar(info.format)) {
        //
    }
    const DXGI_FORMAT tformat = (format == DXGI_FORMAT_UNKNOWN) ? info.format : format;


    //如果是源格式被压缩
    std::unique_ptr<ScratchImage> cimage;
    if (IsCompressed(info.format)) {
        //
    }

    //Undo Premultiplied Alpha (if requested) 代码略

    //Flip/Rotate  代码略

    //Resize 调整图像大小  代码略

    //Swizzle (if requested) 代码略

    //Color rotation (if requested) 代码略

    //Tonemap (if requested)  代码略

    //ColorKey/ChromaKey 略
    //Invert Y Channel  略
    //Reconstruct Z Channel 略

    //Determine whether preserve alpha coverage is required (if requested) 略

    //Generate mips 不确定

    // Preserve mipmap alpha coverage (if requested) 略
    //Premultiplied alpha (if requested) 略
    //Compress 略
    //Set alpha mode 不确定

    //保存
    auto img = image->GetImage(0, 0, 0);
    assert(img);
    const size_t nimg = image->GetImageCount();

    wprintf(L"\n");

    // Figure out dest filename
    std::string output = R"(C:\Users\Administrator\Desktop\ALLData\s1.dds)";
    std::filesystem::path dest(outputDir);
    uint64_t dwOptions = 0;
    DDS_FLAGS ddsFlags = DDS_FLAGS_NONE;
    if (dwOptions & (uint64_t(1) << OPT_USE_DX10))
    {
        ddsFlags |= DDS_FLAGS_FORCE_DX10_EXT | DDS_FLAGS_FORCE_DX10_EXT_MISC2;
    }
    else if (dwOptions & (uint64_t(1) << OPT_USE_DX9))
    {
        if (dxt5rxgb)
        {
            ddsFlags |= DDS_FLAGS_FORCE_DXT5_RXGB;
        }

        ddsFlags |= DDS_FLAGS_FORCE_DX9_LEGACY;
    }
    std::filesystem::path boost_output(output);
    hr = SaveToDDSFile(img, nimg, info, ddsFlags, boost_output.wstring().c_str());

    return 0;
}

3、jpg转ktx2

https://github.com/KhronosGroup/KTX-Software

该项目可以做到,编译出来很多个exe.

用toktx.exe将jpg转换位ktx格式

toktx.exe  C:\Users\Administrator\Desktop\ALLData\s1.ktx   C:\Users\Administrator\Desktop\ALLData\s1.jpg

用ktx2ktx2.exe将ktx转换位ktx2格式

ktx2ktx2.exe  C:\Users\Administrator\Desktop\ALLData\s1.ktx

用ktx2check.exe检验ktx2

ktx2check.exe C:\Users\Administrator\Desktop\ALLData\s1.ktx2

  • 16
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Protobuf是一种高效的序列化协议,可以用于数据交换和数据存储。它的主要优势是大小小,速度快,可扩展性强。下面是使用Protobuf的一些小记: 1. 定义消息格式 首先,需要定义消息格式,以便Protobuf可以将数据序列化和反序列化。消息格式定义在.proto文件中,使用protobuf语言编写。例如,下面是一个简单的消息格式定义: ``` syntax = "proto3"; message Person { string name = 1; int32 age = 2; } ``` 这个消息格式定义了一个名为Person的消息,包含两个字段:name和age。 2. 生成代码 一旦消息格式定义好,就可以使用Protobuf编译器生成代码。编译器将根据消息格式定义生成相应的代码,包括消息类、序列化和反序列化方法等。可以使用以下命令生成代码: ``` protoc --java_out=. message.proto ``` 这将生成一个名为message.pb.java的Java类,该类包含Person消息的定义以及相关方法。 3. 序列化和反序列化 一旦生成了代码,就可以使用Protobuf序列化和反序列化数据。例如,下面是一个示例代码,将一个Person对象序列化为字节数组,并将其反序列化为另一个Person对象: ``` Person person = Person.newBuilder() .setName("Alice") .setAge(25) .build(); byte[] bytes = person.toByteArray(); Person deserializedPerson = Person.parseFrom(bytes); ``` 这个示例代码创建了一个Person对象,将其序列化为字节数组,然后将其反序列化为另一个Person对象。在这个过程中,Protobuf使用生成的代码执行序列化和反序列化操作。 以上是使用Protobuf的一些基本步骤和注意事项,希望对你有所帮助!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

江河地笑

实践是检验真理的唯一标准

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

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

打赏作者

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

抵扣说明:

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

余额充值