环境:VS2017,NX12
目标:RGB颜色选择器控件的返回值是一个RGB数值,如何将其转成NX中颜色区间[1,256]
涉及内容:十六进制,UF函数颜色转换
原理:首先将RGB数值转换成十六进制文本,然后将文本拆分赋值给红、绿、蓝三个子字符串(注意十六进制文本长度),每个子字符串的十六进制文本转成十进制整数,然后十进制整数除以255.0,再调用UF_DISP_ask_closest_color得到结果。
注意:RGB的数值范围很大,但只能得到256个数字,即多对一。反向,256个数字只能得到256个RGB值,即一对一。由此可以总结得到:RGB1->NX->RGB2 如此转换 RGB1不一定等于RGB2。 NX1->RGB->NX2 如此转换NX1 一定等于NX2 。
代码:
#include <map>
#include <vector>
#include <array>
#include <sstream>
#include <string>
#include <iomanip>
#include <NXOpen/Session.hxx>
#include <uf_disp.h>
#include <uf.h>
#include <uf_obj.h>
using namespace std;
using namespace NXOpen;
namespace
{
std::string Dec2Hex(const int &i) //将int转成16进制字符串
{
stringstream ioss; //定义字符串流
string sTemp; //存放转化后字符
ioss << setiosflags(ios::uppercase) << hex << i; //以十六制(大写)形式输出
ioss >> sTemp;
return sTemp;
}
int Hec2Dex(const std::string &value) //将int转成16进制字符串
{
if (value.empty())
{
return 0;
}
return stoi(value, NULL, 16);
}
void SplitHex(const std::string &hex, std::vector<std::string> &rgbColorList)
{
rgbColorList.clear();
std::string redString;
std::string greenString;
std::string blueString;
if (!hex.empty())
{
int size = hex.size();
//可能是一位长度或多位长度,需要区分截断
switch (size)
{
case 1:
{
blueString = hex;
break;
}
case 2:
{
blueString = hex;
break;
}
case 3:
{
greenString = hex.substr(0, 1);
blueString = hex.substr(1);
break;
}
case 4:
{
greenString = hex.substr(0, 2);
blueString = hex.substr(2);
break;
}
case 5:
{
redString = hex.substr(0, 1);
greenString = hex.substr(1, 2);
blueString = hex.substr(3);
break;
}
case 6:
{
redString = hex.substr(0, 2);
greenString = hex.substr(2, 2);
blueString = hex.substr(4);
break;
}
default:
{
std::string postValue = hex.substr(size - 6);
redString = postValue.substr(0, 2);
greenString = postValue.substr(2, 2);
blueString = postValue.substr(4);
break;
}
}
}
rgbColorList.push_back(redString);
rgbColorList.push_back(greenString);
rgbColorList.push_back(blueString);
}
int CalNXColor(const std::vector<std::string>&rgbHexList)
{
if (3 != rgbHexList.size())
{
return 1;
}
double num = 255.0;
double clrValue[3] = { 0.0 };
for (int i = 0; i < rgbHexList.size(); ++i)
{
clrValue[i] = Hec2Dex(rgbHexList[i]) / num;
}
int nxColor = 1;
UF_DISP_ask_closest_color(UF_DISP_rgb_model, clrValue, UF_DISP_CCM_EUCLIDEAN_DISTANCE, &nxColor);
return nxColor;
}
void CompleteTwoLen(std::string &value)
{
if (value.empty())
{
value = "00";
}
else if (1 == value.size())
{
value = "0" + value;
}
else if (2 == value.size())
{
}
else
{
value = value.substr(value.size() - 2);
}
}
//1~256 转长整型 4227200
int ColorToRGBColor(const int &color)
{
char *clrName = NULL;
double clrValues[3] = { 0.0 };
UF_DISP_ask_color(color, UF_DISP_rgb_model, &clrName, clrValues);
UF_free(clrName);
double num = 255.0;
int clrIntValues[3] = { clrValues[0] * num, clrValues[1] * num, clrValues[2] * num };
//整型转16进制,这里需要注意,必须保证是六位长度
std::string hex0 = Dec2Hex(clrIntValues[0]);
std::string hex1 = Dec2Hex(clrIntValues[1]);
std::string hex2 = Dec2Hex(clrIntValues[2]);
CompleteTwoLen(hex0);
CompleteTwoLen(hex1);
CompleteTwoLen(hex2);
std::string hexString = hex0 + hex1 + hex2;
return Hec2Dex(hexString);
}
//长整型 4227200 转 1~256
int RGBColorToColor(const int &rgbColor)
{
std::string hex = Dec2Hex(rgbColor);
std::vector<std::string> rgbList;
SplitHex(hex, rgbList);
int res = CalNXColor(rgbList);
if (res < 1 || res > 256)
{
res = 1;
}
return res;
}
}
extern "C" DllExport void ufusr(char *param, int *retcod, int param_len)
{
UF_initialize();
//nxColor = 1~256
int nxColor = 135;
//rgbColor = 3498129
int rgbColor = ColorToRGBColor(nxColor);
//nxColorNext = 135
int nxColorNext = RGBColorToColor(rgbColor);
UF_terminate();
}
extern "C" DllExport int ufusr_ask_unload()
{
return (int)Session::LibraryUnloadOptionImmediately;
}
extern "C" DllExport void ufusr_cleanup(void)
{
}