请问把byte[]数据重组成图像的方法

weixin_41884234 2018-04-24 01:48:33
加精
我把一个包含多个图像信息的文件,用FileSteam读入缓冲区,并按照指定的格式逐一把图像数据取出,但目前卡在这些数据如何使用上。我从外国网站找到了描述这个数据结构的文件,但他们的书写方式不太理解,希望能有一些window图形编程方面的高手能指教一下。

先介绍下源文件:
1. 这是一个dat格式的文件,是专用格式,里面没有图片格式的关键字或识别码。
2. 文件里主要包含了3个图形组,每个图形组包含了297张图形数据

接下来介绍下外国找到的资料,具体什么编程语言不明。
解释下阅读方法,他这个文件介绍了这个dat文件的数据结构,把dat用filesteam流,按他描述的顺序进行读取和处理,可以正确读出每一个参数的数据。
其中变量后面的.w;.l表示这个变量的长度,例如width.w表示这个变量为2byte,要从流中取2byte的数据。
w=2byte l=4byte b=1byte

Header

unknown.w //不明参数,取出即可,无需使用
width.w
height.w
depthRes.l
paletteFlag.l (bool)//这个值取出后主要用作bool运算

if paletteFlag
paletteEntry.w * 256

dataPos.l //这里取出一个值,表示从文件头开始的偏移值,这个偏移值后就开始是图形数据
imageCount.w //图片组,即开头说到的3

for imageCount
unknown1.l
if unknown1
unknown2.l
//上面这个fos循环主要是把流位置移正确,本身变量含义不用管

frameCount.w
for frameCount
top.w
left.w
bottom.w
right.w
flag.l

if flag & 8 == 0 // hasAlpha
length.l
dataOffset.l

if flag & 4 // hasBase
dataOffset.l
length.l

if flag & 1 // hasDepth
depthType.b //0指WORD / depthRes, 1指BYTE / depthRes, 2指步长  3指填充nearestDist。(看不明白)
val2.w
nearestDist.w
depthOffset.l
depthSize.l

unk2Length.l
if unk2Length
unk2offset.l



Base
Palette
paletteFlag>0的时候
paletteIndex.b * (width * height)


Alpha
-从alpha数据的偏移位置开始
-逐行压缩
rowSize1.l
for height
rowSize2.l
for width * height
data.w //0x7fff 至 555


展開
rowSize = getLong();
for(int i=0; i<height; i++) {
rowSize2 = getLong();
rows[i] = (rowSize2 - rowSize) / 2;
rowSize = rowSize2;
}

for(int y=0; y<height; y++) {
x = 0;
for(int i=0; rows[y]<width; i++) {
data1 = getByte();
data2 = getByte();
for(int j=0; j<((data1 & 7) << 8 | data2); j++) {
data[x++ + y * width] = data1 & 0xf8;
}
}
}

return data;


Depth
1/depthRes 分辨率深度信息

data.w * (ceil(width / depthRes) * ceil(height / depthRes))



最后说说我目前的进展:
我使用他的header,顺利把第0组的297个图片信息读取了出来。但只有这些无法还原图形,望有图形方面知识的专家,能从上图的信息中找出与图形相关的参数或变量,提供一个方法或思路,让我能把这些数据重组成图片。谢谢~

我使用的代码,因为仅考虑读取第0组,所以仅对第一个组的图片进行了遍历取值,没有对3个组都遍历。

//WORD = short LONG = int byte = byte;
//调试用,写死目标文件名
string path = @"C:\test.dat";

//FileStream方式读取文件到缓冲区buff
FileStream test= new FileStream(path, FileMode.Open, FileAccess.Read);
BinaryReader reader = new BinaryReader(test);

//文件头部分,一个文件只有一个文件头
short unknow = reader.ReadInt16();
short width = reader.ReadInt16();//这个貌似不是单个图片的宽度和高度,
short height = reader.ReadInt16();
int depthRes = reader.ReadInt32();
int paletteFlag = reader.ReadInt32();
short[] paletteEntry = new short[256];
if (paletteFlag > 0)
{
for (int pe = 0; pe < 256; pe++) //这里是我解读的,不知道对不对,原文写的是if paletteFlag paletteEntry.w * 256
{
paletteEntry[pe] = reader.ReadInt16();
}
}

int dataPos = reader.ReadInt32(); //文件头偏移值,表示这里开始是图片数据
short imageCount = reader.ReadInt16(); //图形组,值=3

//因为已经知道有297张图片,所以直接建数组来存
short[] top = new short[297];
short[] left = new short[297];
short[] bottom = new short[297];
short[] right = new short[297];
int[] flag = new int[297];
int[] hasAlpha = new int[297];
int[] alpha_legth = new int[297];
int[] alpha_dataOffset = new int[297];
int[] hasBase = new int[297];
int[] base_dataOffset = new int[297];
int[] base_length = new int[297];
int[] hasDepth = new int[297];
byte[] depthType = new byte[297];
short[] val2 = new short[297];
short[] nearestDist = new short[297];
int[] depthOffset = new int[297];
int[] depthSize = new int[297];
int[] unk2Length = new int[297];
int[] unk2Offset = new int[297];

//本来这里要for循环3次,遍历3个组,因为我们只取第一个组,所以取消,直接按顺序读
//unknown变量没有使用到,只是需要按逻辑读取,一面流的位置错误
int unknown1 = reader.ReadInt32();
if (unknown1 > 0)
{
int unknown2 = reader.ReadInt32();
}


short frameCount= reader.ReadInt16(); //每组图片的总数量,这里值为297
for (int n = 0; n < frameCount; n++)
{
top[n] = reader.ReadInt16(); //用着4个点算出来的距离,从值上来看刚好等于单个图片的尺寸
left[n] = reader.ReadInt16();
bottom[n] = reader.ReadInt16();
right[n] = reader.ReadInt16();

flag[n] = reader.ReadInt32(); //unknow point
hasAlpha[n] = flag[n] & 8; // 0:hasAlpha 1:noAlpha
if (hasAlpha[n] == 0)
{
alpha_legth[n] = reader.ReadInt32();
alpha_dataOffset[n] = reader.ReadInt32();
}

hasBase[n] = flag[n] & 4; //0:noBase 1:hasBase
if (hasBase[n] != 0)
{
base_dataOffset[n] = reader.ReadInt32();
base_length[n] = reader.ReadInt32();

}


hasDepth[n] = flag[n] & 1; //0:noDepth 1:hasDepth
if (hasDepth[n] != 0)
{
depthType[n] = reader.ReadByte();//0指WORD / depthRes, 1指BYTE / depthRes, 2指步长  3指填充nearestDist。(这个是网上找到的,具体意思不明)
val2[n] = reader.ReadInt16();
nearestDist[n] = reader.ReadInt16();
depthOffset[n] = reader.ReadInt32();
depthSize[n] = reader.ReadInt32();
}


unk2Length[n] = reader.ReadInt32();
if (unk2Length[n] > 0)
{
unk2Offset[n] = reader.ReadInt32();
}


我用上述代码运行,取出来的数据与网上贴出来的日志比对,可以对得上,证明这个结构可以正确读取。(网上写这个资料的人,已经顺利把数据还原成图像,只是年代久远已经联系不上)

最后提供附件
附件1:如果还原顺利,第[0]张图片应该张这样


附件2:源头dat文件。链接: https://pan.baidu.com/s/1m1XZbHF0MgeBU8g3wdq0Ow 密码: w647
...全文
4016 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
Boom丶Bum 2018-05-08
  • 打赏
  • 举报
回复
我觉得是否适合做程序员不应该靠这个来评价,对于电脑新手而言,对于字体和全角半角符根本就不太了解,也不明白会在程序中造成什么样的错误. 打不打错字是可以练出来的,没有谁说刚接触电脑就可用很熟练的用电脑,都是经过长期的积累和实践的结果.而且打字和键盘上的快捷键什么的,只要愿意学,很快就能学得会. 我觉得是否适合做程序员应该看自己对这方面的热爱和有没有一颗愿意一直踏踏实实一直学下去的心.
weixin_41884234 2018-04-28
  • 打赏
  • 举报
回复
引用 13 楼 zhao4zhong1 的回复:
个人建议楼主趁早转行。 关于自己是否适合编程的很简单的测试: 在报纸或杂志上随便找一段约1000字的文章,在Word中输入一遍。输完后再参考下面答案: A里面有10处以上文字或标点错误 B里面没有文字或标点错误并敢为此跟人打赌 C里面没有文字或标点错误并且字体和排版完全与原稿一致 D打印在半透明的纸上和原稿重叠在一起检查一模一样,且自我感觉很有成就感 A不适合编程(理由:打字准确度偏低、粗心大意) B初级程序员(理由:打字准确度很高、认真细致、自信、理解全角半角概念) C高级程序员(理由:在B的基础上理解字体和排版也是电脑打印的重要因素、但相比D还不够偏执、精益求精、结果可验证) D软件项目经理(理由:能针对项目给出令人信服的细致到极点的需求说明和典型测试用例。用户几乎挑不出毛病。专业!) 如果想从A变成B的话,到我的资源http://download.csdn.net/detail/zhao4zhong1/4084259里面下载“适合程序员的键盘练习”
职业不是程序员,谢谢。我从头到尾都没说自己是做技术的,不知道从哪里下这个判断并且以这个判断来发表和这个问题无关的答案?老师?
赵4老师 2018-04-28
  • 打赏
  • 举报
回复
个人建议楼主趁早转行。 关于自己是否适合编程的很简单的测试: 在报纸或杂志上随便找一段约1000字的文章,在Word中输入一遍。输完后再参考下面答案: A里面有10处以上文字或标点错误 B里面没有文字或标点错误并敢为此跟人打赌 C里面没有文字或标点错误并且字体和排版完全与原稿一致 D打印在半透明的纸上和原稿重叠在一起检查一模一样,且自我感觉很有成就感 A不适合编程(理由:打字准确度偏低、粗心大意) B初级程序员(理由:打字准确度很高、认真细致、自信、理解全角半角概念) C高级程序员(理由:在B的基础上理解字体和排版也是电脑打印的重要因素、但相比D还不够偏执、精益求精、结果可验证) D软件项目经理(理由:能针对项目给出令人信服的细致到极点的需求说明和典型测试用例。用户几乎挑不出毛病。专业!) 如果想从A变成B的话,到我的资源http://download.csdn.net/detail/zhao4zhong1/4084259里面下载“适合程序员的键盘练习”
www_adintr_com 2018-04-28
  • 打赏
  • 举报
回复
你发的第一张图片大小是 193 X 155 日志中显示的图片大小是 374 X 232 日志中第一张图片的区域算出的大小 right - left = 70 - (-95) = 165 bottom - top = 2 - (-143) = 145, 的到的图片大小为 165 X 145 根据描述, Base 的大小为 paletteIndex.b * (width * height), 即 宽度乘以高度 这三组对应的分别是: 193 X 155 = 29915, 374 X 232 = 86768, 165 X 145 = 23925 而你日志中打印出来的 Base 数据大小是: 12256 没一个对得上的, 全是乱的
赵4老师 2018-04-28
  • 打赏
  • 举报
回复
希望你从不打错字起步,先做一个严谨细致的人,再向逻辑思维清晰的码农挺进。
weixin_41884234 2018-04-27
  • 打赏
  • 举报
回复
引用 10 楼 schlafenhamster 的回复:
你那个 图片 有 alpha 有 depth 是 potoshop 的 图片吗 ?

应该不是,应该是一个bmp格式的位图文件。我再上传一个例子,图数和尺寸都小一点,看能不能有助于降低分析难度

链接:https://pan.baidu.com/s/1_rjanlY6EpYvZWp2hfFV2w 密码:cceu

这个dat里有3组图片,每组8张,其中第一组,即imageCount[0]的图片是一个路牌,如果格式正确,第1组第1、2张图片应该长这样



schlafenhamster 2018-04-27
  • 打赏
  • 举报
回复
你那个 图片 有 alpha 有 depth 是 potoshop 的 图片吗 ?
weixin_41884234 2018-04-27
  • 打赏
  • 举报
回复
还有其他大神有方法吗
weixin_41884234 2018-04-24
  • 打赏
  • 举报
回复
这个日志是网上那个人贴出来的,最开始我就是用最粗暴的方法去核对他提供的数据结构是否正确。逐个数据取出来和他日志进行比对

weixin_41884234 2018-04-24
  • 打赏
  • 举报
回复
引用 2 楼 hhhh63 的回复:
以下是我把CT数据转换为图像的实例,256色,用CImage类 CImage m_cimage;
	if( m_cimage.IsNull() )
	{
		m_cimage.Create( imgw4, -imgh-1, 8 );	// 负高度表示原点在左上角,img.GetBits(); 得到数据区的起点。	// 20150310 imgw 改为imgw4 加宽的图像
		RGBQUAD * pp = (RGBQUAD*)(theApp.palbuffer + 8 + sizeof(UINT)*2 /*+ (256*4+8)*3*/);
		m_cimage.SetColorTable( 0, 256, pp );
	}

	LPBYTE p = (LPBYTE)m_cimage.GetBits();
	LPWORD p2 = pimgdata1;
	//const int w2 = (imgw + 0x3) & ~0x3;	//?? 实际宽度是4的倍数?是否与操作系统或硬件有关。
	WORD threshold = tbg_threshold ? roundint( tbg_threshold * kt * 0.95 ) : temperaturemin;	// 背景和人体分界点
	//ASSERT( !tbg_threshold );
	int dd = temperaturemax - threshold;	// 窗宽
	if( dd < roundint(5 * kt) )		// 设置温差最小值为10度,防止除零、未初始化等等。
		dd = roundint(5 * kt);
	for( int i = 0; i < imgh; i++ ){
		int j = 0;
		for( ; j < imgw; j++ )
		{
			int w = (*p2++ - threshold) * 255 / dd;
			if( w < 0 ) w = 0;
			if( w > 255 ) w = 255;
			*p++ = (BYTE)w;
		}
		for( ; j < imgw4; j++, p++ );	//?? 补齐多余的宽度?
	}

	m_cimage.StretchBlt( hDestDC, drc, orc, dwRop );
谢谢~我琢磨下看能不能应用
weixin_41884234 2018-04-24
  • 打赏
  • 举报
回复
引用 1 楼 schlafenhamster 的回复:
请 把 第[0]张图片 的数据 和 有关信息 用 HexWin 转成 text 文件
链接: https://pan.baidu.com/s/1VxnuW0ad7fbz3SDnFtZl5g 密码: 1jus 压缩包包含了alpha,base,depth。但是一开始的palette没有,主要是对palette不了解,我是用256容量的数组去取了值,取出来的值如下 https://shimo.im/sheet/Pe3UEuwKWosDdEsv/ 点击链接查看「paletteEntry[256]」
hhhh63 2018-04-24
  • 打赏
  • 举报
回复
以下是我把CT数据转换为图像的实例,256色,用CImage类 CImage m_cimage;
	if( m_cimage.IsNull() )
	{
		m_cimage.Create( imgw4, -imgh-1, 8 );	// 负高度表示原点在左上角,img.GetBits(); 得到数据区的起点。	// 20150310 imgw 改为imgw4 加宽的图像
		RGBQUAD * pp = (RGBQUAD*)(theApp.palbuffer + 8 + sizeof(UINT)*2 /*+ (256*4+8)*3*/);
		m_cimage.SetColorTable( 0, 256, pp );
	}

	LPBYTE p = (LPBYTE)m_cimage.GetBits();
	LPWORD p2 = pimgdata1;
	//const int w2 = (imgw + 0x3) & ~0x3;	//?? 实际宽度是4的倍数?是否与操作系统或硬件有关。
	WORD threshold = tbg_threshold ? roundint( tbg_threshold * kt * 0.95 ) : temperaturemin;	// 背景和人体分界点
	//ASSERT( !tbg_threshold );
	int dd = temperaturemax - threshold;	// 窗宽
	if( dd < roundint(5 * kt) )		// 设置温差最小值为10度,防止除零、未初始化等等。
		dd = roundint(5 * kt);
	for( int i = 0; i < imgh; i++ ){
		int j = 0;
		for( ; j < imgw; j++ )
		{
			int w = (*p2++ - threshold) * 255 / dd;
			if( w < 0 ) w = 0;
			if( w > 255 ) w = 255;
			*p++ = (BYTE)w;
		}
		for( ; j < imgw4; j++, p++ );	//?? 补齐多余的宽度?
	}

	m_cimage.StretchBlt( hDestDC, drc, orc, dwRop );
schlafenhamster 2018-04-24
  • 打赏
  • 举报
回复
请 把 第[0]张图片 的数据 和 有关信息 用 HexWin 转成 text 文件
weixin_41884234 2018-04-24
  • 打赏
  • 举报
回复
引用 6 楼 schlafenhamster 的回复:
说明 “外国找到的资料” 的 出处
是外国一个校园网论坛的技术板块,得该学校的内网ip才能访问。我估计五一后会去那边。。如果这段时间没有啥进展,我到时去到那边把他原帖子再拷贝一下,原贴是英文的,上面部分是我翻译过的,也有可能是翻译不到位导致理解有偏差
schlafenhamster 2018-04-24
  • 打赏
  • 举报
回复
说明 “外国找到的资料” 的 出处
 OpenGL-自主高性能三维GIS平台架构与实现/第二季:实现三维GIS球体+ 高程数据章节名称DEM基础1DEM基础知识1.介绍基本的DEM知识2.什么是DEM,作用是什么2DEM数据1.如何获取/ 传统测量/激光扫描/无人机测量/ 点云数据/ 倾斜摄影2.如何使用/局部小规模(栅格数据,图片/tif),3. 组织方式4. 根据使用目的不同,介绍多种优化方法3DEM图层的实现原理14DEM数据结构定义struct  V3U3N4顶点数据的生成和计算WGS84投影计算5wgs84 投影球体被切成一个个小圆弧,一共60个投影带,分别为01,02.........60WGS的最新版本为WGS 84(也称作WGS 1984、EPSG:4326),1984年定义、最后修订于2004年。接口定义坐标转换Wgs84 数据加载6瓦片编号计算生成算法1. 经纬度到大地坐标的转换2.大地坐标到经纬度坐标转换3. 根据经纬度获取瓦片编号框架构7智能指针构框架1. 基类定义(所有的类继承自基类),基类派生自 std::enbale_shared_from_this2. 实现智能指针的动态转换接口3. 实现向下转换4. 已有的类实现全部使用智能指针构5. 任务系统(多线程加载任务)8引入图层(Layer)1. 介绍图层的概念以及要性2. 图层类实现3. 修改框架(使用图层的方式构框架)9Layer-bug排查(绘制过程中出现错位,偶发)1. 框架构后遇到问题(绘制结果错误)2. 瓦片索引方式发生变化,多线程中引起内存问题3. 修改索引方式,解决绘制偶发错误问题10引入数据源(TileSource)1. 数据源的作用与设计目的2. 当前存在的问题,数据调度中存在问题3. 数据源(TileSource)类实现11数据格式管理(FormatMgr)1. 数据格式管理(FormatMgr) 提出的目的,需要解决的问题2. CELLFormat基类接口抽象3. 实现几个标准格式类4. 修改框架流程,使用FormatMgr构流程5. 扩展支持,后续支持任务格式数据加入系统12Task(任务)优化1. 任务中低耦合数据结构,目的是让Task更加的通用2. 修改任务读取代码与任务处理代码,完善处理流程DEM高程13DEM-数字高程定义1. 什么是数字化高程数据2. 当下GIS系统中有哪些常见的高程格式3. 课程体体系中使用的哪种格式4. 高程类定义以及实现,并加入到FormatMgr 管理系统中14高程瓦片数据读取1. 介绍GIS系统相关的工具(在数据转换)数据生成方面可以解决大量时间2. 自定义高程瓦片格式说明3. 自定义高程格式文件解析,并以智能对象的方式引入到系统中4. 完善框架代码,适配高程数据15高程瓦片文件的读取1. 实现基本的读取算法2. 增加格式化组件,并加入到系统中3. 配置高程图层以及高程数据源,并加载数据,验证数据正确性16瓦片数据结构构1.顶点生成2.UV坐标计算3.面数据生成17DEM构绘制流程1. 修改绘制数据结构,去除无用字段2. 增加Mesh类,实现光栅数据转换成三角面数据,计算UV数据,提炼接口3. 修改系统调度,实现顶点数据,UV数据,以及面数据的生成与更新4. 按需更新数据,而不是每一帧更新18DEM-数据精度问题(CPU)1. 因为瓦片数据使用大地坐标作为系统输入,造成瓦片坐标很大,单浮点数据精度不够2. 使用局部坐标的方式解决单浮点精度问题3. 调整相机参数,解决投影矩阵数据计算深度精度问题4. 修改绘制shader 实现对瓦片数据的绘制19DEM-数据精度问题(LogDepth)1. 使用对数深度(log depth )算法在GPU中 计算解决单浮点经纬计算问题2. 修改shader ,增加对(logDepth)算法支持3. 修改C++端代码,实现对shader数据的输入20DEM-数据结构优化1.当下使用CPU端数据通过接口的方式传递给GPU,速度慢2. 使用Instance 方式降低Vertex Buffer 的大小,优化渲染系统21DEM-GPU缓冲区优化1. 使用Vertex Buffer Object / Index Buffer Object  / Instance  方式优化渲染系统2. 修改绘制接口,使用DrawElementsInstanceBaseInstance方式提升系统性能内存池与对象池22瓦片生成优化/对象池1. 相机移动过程中会频繁的建立与释放瓦片,对CPU有较大的消耗2. 引入内存池,避免频繁的内存申请与释放,降低CPU时间3. 改造智能指针对象,对象释放通知到内存管理,回收对象内存23改造任务系统支持对象池1. 任务系统是一个公用模块,被多个模块使用,避免频繁的内存操作,引起的内存碎片2. 实现对象池,并应用到任务模块法线计算24法线计算1. 修改现有顶点结构,增加法线支持2. 修改shader,增加法线顶点输入,使用平行光光照模型3. 修改绘制流程,支持光照计算,使用探照灯作为光源输入25顶点法线计算/共享法线计算1. 增加数据结构保存顶点数据被多个面共享的次数2. 计算面法线,并累加到顶点法线中3. 根据顶点被面共享的次数做平均法线计算4. 修改流程,按需更新法线数据26法线数据压缩1. 法线数据使用3 * float 数据存储,大大的增加了系统的数据2. 实现算法,将3 * float 数据压缩成4字节数据3. 改造绘制代码,支持压缩数据输入27GPU中计算产生法线数据(去掉CPU中计算)1. 引擎支持 Geometry Shader 阶段2. 编写 Geometry Shader,实现法线计算系统功能优化28构CPU拾取流程1. 当下的拾取流程,只支撑二维数据拾取,无法准群的拾取三维数据2. Terrain中增加拾取接口,输入射线,输出拾取到顶点数据29绘制拾取结果1. 增加一个绘制点的方法,实现绘制代码2. 修改shader,增加logdepth3. 调试代码,花费了很多时间排查错误,最总排查到是因为uniform参数笔误写错造成。30任务系统完善,避免任务队列无线膨胀1. 任务系统中,没有限制队列的大小,生产者的能力远大于消费者的能力,造成任务队列膨胀2. 处理办法,限制生产者的生产能力,而不是限制任务队列大小(这种方式会造成业务逻辑异常复杂)3. 使用sleep休眠方式(这种方式是严错误的)31如何避免瓦片数据抖动1. 产生瓦片抖动的原因 ? 分裂算法与回退算法中间没有过度2. 引入过度流程,避免内存抖动,参数因子是一个要的数据,需要谨慎使用3. 有必要结合瓦片自身数据动态计算参数因子32瓦片数据管理-fepk文件格式支持-全球数据加载1. 支持fepk文件格式,增加fepk读取组件,适配fepk文件2. fepk管理数据方式:一般情况选择全球前10级别作为基础级别,因数据量不大(1G)左右,后续以8级作为基础级别,全球19级别数据被划分为 2^8 * 2^7(512 * 256)个块。每个块中包含了256 * 256 张小瓦片33fepk高程数据读取 34高程分裂处理当瓦片没有高程数据,那么子节点以及其他后代节点该如何共享父节点的数据35lesson-734-高程瓦片分裂处理(2)-算法实现高程数据分裂算法实现实现对高程数据的切分,并对特殊数据进行处理36高程瓦片分裂处理(3)-问题排查 37高程瓦片分裂处理(4)-(后代节点更新问题)当一个瓦片高程数据更新后,他的儿子节点,孙子节点...该如何处理?38瓦片视锥裁剪错误高程数据更新后,没有技术计算瓦片包围盒信息,造成包围盒错误,进而引视锥计算错误39http支持1.引入三方库 Libcurl2.http类封装,支持http读取数据40fepk.server使用 生成三维地球41改造四叉树-统一使用经纬度输入42地形网络生成算法构 43引入球体坐标系 44使用球体坐标改造瓦片 45多图层(加载标签数据) 课时截图:镜头拉近后,显示细节数据加载矢量SHP国界线数据:加载矢量三维白膜数据截图高程数据加载点云数据 加载倾斜摄影数据 

19,468

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧