VTK颜色映射处理

  1. 颜色查找表

  1. 我们可以手动创建一个颜色查找表,如果没有创造的话,贴心的vtk会自动为我们生成一个默认的颜色查找表,颜色查找表中允许我们自由设定颜色值。vtkLookupTable可以帮助我们来完成这个工作,同时,设定了颜色数量时,SetTabValue()方法可以将颜色值插入到指定的位置。另外,SetScalarRange()告诉我们采取什么方法映射,标量值大于最大值的将被归为最大值,标量值小于最小值的将被归为最小,因为颜色索引是根据属性的最值建立的。

颜色映射的过程主要包括以下步骤:
    1)定义颜色表,在颜色表中用数组保存所定义的颜色组分(红、绿、蓝)。
     2)将颜色表和属性数据关联。

     3)根据属性数据的最大、最小值建立颜色索引


  1.  //定义颜色映射表  
  2.     vtkLookupTable *pColorTable=vtkLookupTable::New();  
  3.     //设置颜色表中的颜色  
  4.     pColorTable->SetNumberOfColors(8);  
  5.     /*pColorTable->SetTableValue(0,1.0,0.0,0.0,1.0);*/  
  6.     pColorTable->SetTableValue(0,1.0,0.0,0.0,1.0);  
  7.     pColorTable->SetTableValue(1,0.0,1.0,0.0,1.0);  
  8.     pColorTable->SetTableValue(2,1.0,1.0,0.0,1.0);  
  9.     pColorTable->SetTableValue(3,0.0,0.0,1.0,1.0);  
  10.     pColorTable->SetTableValue(4,1.0,0.0,1.0,1.0);  
  11.     pColorTable->SetTableValue(5,0.0,1.0,1.0,1.0);  
  12.     pColorTable->SetTableValue(6,1.0,1.0,1.0,1.0);  
  13.     pColorTable->SetTableValue(7,0.0,0.0,0.0,1.0);  
  14.     pColorTable->Build();  
  15.     //数据映射  
  16.     vtkPolyDataMapper *cubeMapper = vtkPolyDataMapper::New();  
  17.     cubeMapper->SetInputData(cube);  
  18.     cubeMapper->SetScalarRange(0,7);  
  19.     cubeMapper->SetLookupTable(pColorTable);  
  20.     vtkActor *cubeActor = vtkActor::New();  
  21.     cubeActor->SetMapper(cubeMapper);  

点击打开链接https://blog.csdn.net/webzhuce/article/details/78077561?locationNum=4&fps=1

颜色映射

  颜色映射的操作对象是数据集中的标量属性。它是一种常用的 标量算法。它会根据数据集中各个部分不同的标量值,对各个部分上不同的颜色。与此相关的另一种上色方法是控制演员的颜色属性,但这样整个图形只有单一的颜色,这显然没有颜色映射方法灵活。 
  创建多边形数据集程序运行 结果显示的彩色立方体就用到了颜色映射。由于对 立方体的6个顶点设置了不同的标量值(点id),所以这6个点的颜色不同。至于立方体其他部分的颜色,也是通过标量值映射来的,不过这些标量值并不是手动设置,而是根据邻近的顶点的标量值,运用某种内插算法计算出来的。

颜色映射过程

  假设有一个共256种颜色的查询表,且颜色的索引号范围为0~255,那么颜色映射就是将数据集的标量值映射到这些索引号的过程。在渲染时,与索引号对应的颜色将作为数据中相应部分的颜色显示出来。映射的方法如下图所示。 
   
这里写图片描述

  上图中,scalar表示数据集中的标量值,index表示映射后的索引号。smin和smax表示的是标量值的映射范围(注意不是数据集中标量值的取值范围)。若一个标量值小于smin,则其映射的索引号为0;若一个标量值大于smax,其映射的索引号为255;若一个标量值在这个范围之间,则映射过程就是一个求一元一次函数值的过程,其对应的曲线是一条直线,不过需要对函数值取整。实际上,在范围外的标量值也可以被看作smin和smax,然后对其求函数值。 
  在VTK中,颜色映射的过程是由映射器mapper完成的。可以通过调用映射器的方法SetScalarRange()来设置标量值的范围[smin, smax]。映射过程只是为每个标量值确定了一个索引号,最终该标量值映射为何种颜色,还需要看颜色查询表中颜色的分配情况。如果不手动创建一个查询表,则映射器会使用一个默认的映射表。

示例演示

CMakeLists.txt文件代码如下:

CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
PROJECT(LookupTableExample)
FIND_PACKAGE(VTK REQUIRED)
INCLUDE(${VTK_USE_FILE})
ADD_EXECUTABLE(LookupTableExample lookuptable.cpp)
TARGET_LINK_LIBRARIES(LookupTableExample ${VTK_LIBRARIES})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

C++代码:

#include "vtkActor.h"
#include "vtkCellArray.h"
#include "vtkFloatArray.h"
#include "vtkPointData.h"
#include "vtkPoints.h"
#include "vtkPolyData.h"
#include "vtkPolyDataMapper.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkRenderer.h"
#include <vtkLookupTable.h>
#include "vtkSmartPointer.h"

int main()
{
    int i;
    //定义立方体的顶点坐标
    static float x[8][3] = { { 0, 0, 0 }, { 1, 0, 0 }, { 1, 1, 0 }, { 0, 1, 0 },
    { 0, 0, 1 }, { 1, 0, 1 }, { 1, 1, 1 }, { 0, 1, 1 } };
    //定义单元,每4个顶点建立一个四边形单元,共计6个单元
    static vtkIdType pts[6][4] = { { 0, 1, 2, 3 }, { 4, 5, 6, 7 }, { 0, 1, 5, 4 },
    { 1, 2, 6, 5 }, { 2, 3, 7, 6 }, { 3, 0, 4, 7 } };
    //创建对象
    vtkSmartPointer<vtkPolyData> cube = vtkSmartPointer<vtkPolyData>::New();
    vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
    vtkSmartPointer<vtkCellArray> polys = vtkSmartPointer<vtkCellArray>::New();
    //存储顶点
    for (i = 0; i < 8; i++)
        points->InsertPoint(i, x[i]);
    //设定单元
    for (i = 0; i < 6; i++)
        polys->InsertNextCell(4, pts[i]);

    //存储标量值
    vtkSmartPointer<vtkFloatArray> scalars = vtkSmartPointer<vtkFloatArray>::New();
    //设定每个顶点的标量值
    for (i = 0; i < 8; i++)
        scalars->InsertTuple1(i,  i*4);
    //创建多边形数据
    cube->SetPoints(points);
    //设定单元类型为多边形
    cube->SetPolys(polys);
    //设定每个顶点的标量值
    cube->GetPointData()->SetScalars(scalars);
    //定义颜色映射表
    vtkSmartPointer<vtkLookupTable> pColorTable = vtkSmartPointer<vtkLookupTable>::New();
    //设置颜色表中的颜色
    pColorTable->SetNumberOfColors(256);
    pColorTable->SetHueRange(0.67, 0.0);        //色调范围从红色到蓝色
    pColorTable->Build();
    //数据映射
    vtkSmartPointer<vtkPolyDataMapper> cubeMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
    cubeMapper->SetInputData(cube);
    cubeMapper->SetScalarRange(0, 7);
    cubeMapper->SetLookupTable(pColorTable);
    vtkSmartPointer<vtkActor> cubeActor = vtkSmartPointer<vtkActor>::New();
    cubeActor->SetMapper(cubeMapper);

    vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
    vtkSmartPointer<vtkRenderWindow> renWin = vtkSmartPointer<vtkRenderWindow>::New();
    renWin->AddRenderer(renderer);
    vtkSmartPointer<vtkRenderWindowInteractor> iren = vtkSmartPointer<vtkRenderWindowInteractor>::New();
    iren->SetRenderWindow(renWin);
    renderer->AddActor(cubeActor);
    renderer->SetBackground(1, 1, 1);
    renWin->SetSize(500, 500);
    renWin->Render();
    iren->Start();
    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70

运行结果:

这里写图片描述

分析

有时候,标量数据就是颜色值,并不需要通过查询表进行映射。对此,映射器提供了以下一些方法来进行控制。 
● SetColorModeToDefault()该方法执行默认的映射器行为,即把unsigned char类型的标量属性数据当作颜色值,不执行隐式。对于其他类型的标量数据,将通过查询表映射。 
● SetColorModeToMapScalars()无论变量数据是何种类型,该方法都通过查询表对标量数据进行映射。如果标量数据的每个元组有多个分量,则对第0个分量进行映射。 

注意事项: 
1. 如果没有标量数据,则映射器将不能使用查询表控制对象的颜色。这时可以使用演员对象来控制颜色。 
2. 如果想阻止颜色映射,可调用映射器的ScalarVisibilityOff()方法。

调用ScalarVisibilityOn()方法后,可以控制映射器的颜色映射行为: 
● SetScalarModeToDefault()执行默认的映射行为:如果有点标量属性数据,则用其进行映射,如果没有点标量属性数据但有单元标量属性数据,则用单元标量属性数据进行映射,否则不映射。 
● SetScalarModeToUsePointData()总是使用点标量属性数据进行映射的。如果没有嗲按标量属性数据,就不进行映射。 
● SetScalarModeToUseCellData()总是使用单元标量属性数据进行映射的。如果没有单元标量属性数据,就不进行映射。 
● SetScalarModeToUsePointFieldData()不使用点或单元标量属性数据,而是使用点属性数据中的一般属性数据来进行映射的。该方法应该与ColorByArrayComponent()结合使用,以用来指定用于颜色映射的数据。 
● SetScalarModeToUseCellFieldData()不使用点或单元标量属性数据,而是使用单元属性数据中的一般属性数据来进行映射的。该方法应该与ColorByArrayComponent()结合使用,以用来指定用于颜色映射的数据。

点击打开链接https://blog.csdn.net/shenziheng1/article/details/54846277

1.符号化Glyphing再谈

上一篇帖子提到一个事,就是用符号化操作显示单元的法向量。
模型的法向量数据是向量数据,因此法向量不能像前面讲到的通过颜色映射来显示。但是可以通过符号化(Glyphing)技术将法向量图形化显示。Glyphing是一种基于图形的可视化技术,这些图像可以是简单的基本图形,如具有方向的椎体,也可以是更加复杂的图像。VTK中就是应用vtkGlyph3D类实现该功能的,并且可以支持Glyphing图形的缩放、着色、设置空间姿态等。使用该类时,需要接受两个输入:一个是需要显示的几何数据点集合;另一个是Glyph图形数据,为vtkPolyData数据。
     
由于读入的模型数据比较大,点比较多,因此使用vtkMaskPoints类采样部分数据,该类保留输入数据中的点数据及其属性,并支持点数据的采样。为了减小计算量,随机采样了300个点做Glyphing显示。将其输出作为vtkGlyph3D的输入数据,而SetSourceData()设置了一个VTKArrowSource数据作为源数据,这样的效果是在输入数据的每一个点处会显示一个Glyph图形,这里我选用的就是箭头图形。vtkGlyph3D::SetVectorModeToUseNormal()指定要使用法向量数据来控制Glyph图形方向。vtkGlyph3D::SetScaleFactor()则控制Glyph图形的大小。

2.曲率计算

曲率时曲面弯曲程度的一种度量,是几何体的一种重要的局部特征。如下图所示:

要计算曲面上给定点M的曲率,考虑经过M的法线的一个平面与曲面相交,得到一条二维曲面,称之为曲面在M点的一条法截线。经过M点法向量的曲面可以任意旋转,即可得到任意多条法截面,如上图所示。每一条法截线都会对应一个曲率,取具有最大曲率和最小曲率的两条法截线为主法截线,例如上图中的C1,C2;其对应的曲率分别记为k1,k2;称为主曲率;高斯曲率等于主曲率的乘积即k1*k2;平均曲率等于主曲率k1,k2的平均值,即(k1+k2)/2;当然,这只是曲率的直观几何解释,并没有给出具体的计算公式。这个公式高中就接触过:

vtk中vtkCurvatures类实现了四种计算网格模型点曲率的计算方法。该类接受一个vtkPolyData数据,经计算得到的曲率数据作为网格模型的点的属性数据存入返回的vtkPolyData中
下例实现了一个网格模型的曲率计算,并通过颜色映射表来显示模型的表面曲率:
[cpp]  view plain  copy
  1. <span style="font-size:18px;">#include <vtkAutoInit.h>  
  2. VTK_MODULE_INIT(vtkRenderingOpenGL);  
  3. VTK_MODULE_INIT(vtkInteractionStyle);  
  4. VTK_MODULE_INIT(vtkRenderingFreeType);  
  5.   
  6. #include <vtkSmartPointer.h>  
  7. #include <vtkPolyDataReader.h>  
  8. #include <vtkCurvatures.h>  
  9. #include <vtkLookupTable.h>  
  10. #include <vtkPolyDataMapper.h>  
  11. #include <vtkActor.h>  
  12. #include <vtkScalarBarActor.h>  
  13. #include <vtkPointData.h>  
  14. #include <vtkRenderer.h>  
  15. #include <vtkRenderWindow.h>  
  16. #include <vtkRenderWindowInteractor.h>  
  17.   
  18. int main()  
  19. {  
  20.     vtkSmartPointer<vtkPolyDataReader> reader =  
  21.         vtkSmartPointer<vtkPolyDataReader>::New();  
  22.     reader->SetFileName("fran_cut.vtk");  
  23.     reader->Update();  
  24.       
  25.     vtkSmartPointer<vtkCurvatures> curvaturesFilter =  
  26.         vtkSmartPointer<vtkCurvatures>::New();  
  27.     curvaturesFilter->SetInputConnection(reader->GetOutputPort());  
  28.     //curvaturesFilter->SetCurvatureTypeToMinimum(); //最小曲率  
  29.     curvaturesFilter->SetCurvatureTypeToMaximum();   //最大曲率  
  30.     //curvaturesFilter->SetCurvatureTypeToGaussian();//高斯曲率  
  31.     //curvaturesFilter->SetCurvatureTypeToMean();    //平均曲率  
  32.     curvaturesFilter->Update();  
  33.   
  34.     double scalarRange[2];  
  35.     curvaturesFilter->GetOutput()->GetScalarRange(scalarRange);  
  36.     //建立查找表 做颜色映射  
  37.     vtkSmartPointer<vtkLookupTable> lut =  
  38.         vtkSmartPointer<vtkLookupTable>::New();  
  39.     lut->SetHueRange(0.0, 0.6);  
  40.     lut->SetAlphaRange(1.0, 1.0);  
  41.     lut->SetValueRange(1.0, 1.0);  
  42.     lut->SetSaturationRange(1.0, 1.0);  
  43.     lut->SetNumberOfTableValues(256);  
  44.     lut->SetRange(scalarRange);  
  45.     lut->Build();  
  46.     ///  
  47.     vtkSmartPointer<vtkPolyDataMapper> mapper =  
  48.         vtkSmartPointer<vtkPolyDataMapper>::New();  
  49.     mapper->SetInputData(curvaturesFilter->GetOutput());  
  50.     mapper->SetLookupTable(lut);  
  51.     mapper->SetScalarRange(scalarRange);  
  52.   
  53.     vtkSmartPointer<vtkActor> actor =  
  54.         vtkSmartPointer<vtkActor>::New();  
  55.     actor->SetMapper(mapper);  
  56.   
  57.     vtkSmartPointer<vtkScalarBarActor> scalarBar =  
  58.         vtkSmartPointer<vtkScalarBarActor>::New();  
  59.     scalarBar->SetLookupTable(mapper->GetLookupTable());  
  60.     scalarBar->SetTitle(curvaturesFilter->GetOutput()->GetPointData()->GetScalars()->GetName());  
  61.     scalarBar->SetNumberOfLabels(5); //设置5个标签  
  62.   
  63.     vtkSmartPointer<vtkRenderer> render =  
  64.         vtkSmartPointer<vtkRenderer>::New();  
  65.     render->AddActor(actor);  
  66.     render->AddActor2D(scalarBar);  
  67.     render->SetBackground(0, 0, 0);  
  68.   
  69.     vtkSmartPointer<vtkRenderWindow> rw =  
  70.         vtkSmartPointer<vtkRenderWindow>::New();  
  71.     rw->AddRenderer(render);  
  72.     rw->SetSize(640, 480);  
  73.     rw->SetWindowName("Calculating PolyData Curvature");  
  74.   
  75.     vtkSmartPointer<vtkRenderWindowInteractor> rwi =  
  76.         vtkSmartPointer<vtkRenderWindowInteractor>::New();  
  77.     rwi->SetRenderWindow(rw);  
  78.     rwi->Initialize();  
  79.     rwi->Start();  
  80.     return 0;  
  81. }</span>  

首先读入一个vtkPolyData人脸模型数据,作为vtkCurvatures的输入,并调用SetCurvatureTypeToMaximum()函数计算最大曲率,此外我们还可以定义最小曲率,高斯曲率,平均曲率。当然,四种曲率允许同时计算。
在内部计算完曲率数据后,将其作为输出的vtkPolyData点的属性数据。保存属性数据时,四种曲率数据分别对应属性名字为Minimum_Curvature/M aximum_Curvature/Gauss_Curvature/Mean_Curvature,因此可以通过属性名字获取相应的曲率数据。例如要获得高斯曲率数据,可调用:
[cpp]  view plain  copy
  1. <span style="font-size:18px;">vtkDoubleArray *gauss = static_cast<vtkDoubleArray*>(  
  2. curvaturesFilter->GetOutput()->GetpointData()->GetArray("Gauss_Curvature"));</span>  
为了能够在模型上显示曲率属性数据,采用颜色映射来显示。定义了一个256色的VTKLookupTable对象,并设置了曲率数据的范围。
然后将改颜色映射表添加到vtkPolyDataMapper中。
最后,我用到了一个新的VTKScalarBarActor类,该类支持一个颜色映射表转换为一个Actor对象,将颜色表以图形的形式显示,并支持设置图形相应的名字和翔实数据Label个数。最后显示即可。

3.参看资料

1.《C++ primer》
2.《The VTK User’s Guide – 11thEdition》
3.  张晓东, 罗火灵. VTK图形图像开发进阶[M]. 机械工业出版社, 2015.

  • 6
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: vtkLookupTablevtk中的一个类,用于将标量值映射颜色和透明度。在分割数据时,可以使用vtkLookupTable来将不同标量值映射到不同的颜色,以便更好地可视化数据。 以下是使用vtkLookupTable进行数据分割的基本步骤: 1. 创建vtkLookupTable对象,并设置其范围和颜色映射方式。例如: ```c++ vtkSmartPointer<vtkLookupTable> lut = vtkSmartPointer<vtkLookupTable>::New(); lut->SetRange(0.0, 1.0); lut->SetValueRange(0.0, 1.0); lut->SetHueRange(0.0, 1.0); lut->SetSaturationRange(1.0, 1.0); lut->SetAlphaRange(1.0, 1.0); lut->Build(); ``` 2. 创建vtkPolyDataMapper对象,并设置其输入数据和颜色映射表。例如: ```c++ vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New(); mapper->SetInputData(polyData); mapper->SetLookupTable(lut); mapper->SetScalarRange(0.0, 1.0); ``` 3. 创建vtkActor对象,并将vtkPolyDataMapper对象添加到其中。例如: ```c++ vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New(); actor->SetMapper(mapper); ``` 4. 将vtkActor对象添加到vtkRenderer中,并设置渲染窗口大小和背景颜色。例如: ```c++ vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New(); renderer->AddActor(actor); renderer->SetBackground(0.1, 0.2, 0.4); renderer->SetViewport(0.0, 0.0, 1.0, 1.0); renderer->ResetCamera(); vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New(); renderWindow->AddRenderer(renderer); renderWindow->SetSize(500, 500); ``` 5. 显示vtkRenderWindow对象。例如: ```c++ vtkSmartPointer<vtkRenderWindowInteractor> interactor = vtkSmartPointer<vtkRenderWindowInteractor>::New(); interactor->SetRenderWindow(renderWindow); interactor->Initialize(); interactor->Start(); ``` 以上是使用vtkLookupTable进行数据分割的基本步骤。具体实现可能会因为数据类型和需求的不同而有所差异,但大致流程相同。 ### 回答2: vtkLookupTable是一个用于颜色映射的类,可以根据输入的标量值对颜色进行分割。 首先,我们需要创建一个vtkLookupTable对象。可以设置这个对象的最小值和最大值,以及想要映射颜色数量。通过设置这些参数,我们可以决定如何将输入的标量值映射颜色空间中。 然后,我们可以使用vtkLookupTable的Build()方法来生成颜色映射表。在生成映射表之前,我们需要通过SetTableValue()方法来设置映射表中每个颜色对应的标量值。为了方便起见,vtkLookupTable还提供了一些预定义的调色板,比如灰度色调、彩虹色调等。 接下来,我们可以将vtkLookupTable应用到我们想要进行颜色映射的数据上。通过vtkScalarsToColors类的MapScalars()方法,可以将输入的标量值转换为对应的颜色值。这样,我们就可以得到一个带有颜色映射的结果数据。 最后,我们可以将带有颜色映射的结果数据进行可视化。通过vtkPolyDataMapper类的SetLookupTable()方法,可以将vtkLookupTable应用到数据的颜色属性上。然后,通过创建vtkActor对象和设置相应的属性(如点大小、线宽等),我们可以将结果数据可视化出来。 综上所述,使用vtkLookupTable可以方便地对输入的标量值进行颜色分割,以实现数据的可视化。 ### 回答3: vtkLookupTable是一个VTK库中的类,用于将输入数据根据设定的颜色表进行分割。颜色表是一组有序的颜色,每个颜色与一个数值范围相关联。使用vtkLookupTable可以将输入数据按照数值范围分割为不同的颜色区域,并为每个区域分配对应的颜色。 使用vtkLookupTable进行分割的步骤如下: 1. 创建vtkLookupTable对象:通过调用vtkLookupTable类的构造函数,创建一个空的颜色表对象。 2. 设置颜色表的数值范围:使用SetTableRange方法,设置颜色表的数值范围。这个范围是根据需要分割的输入数据的最小值和最大值来确定的。 3. 设置颜色表的颜色:使用SetColor方法,为颜色表中的每个数值范围分配一个颜色。可以选择使用预定义的颜色,也可以设置自定义的颜色。可以根据输入数据的不同数值范围设置不同的颜色,使得不同数值区域可以有不同的颜色。 4. 获取颜色表:使用vtkLookupTable的GetLookupTable方法,获取最终生成的颜色表对象。 5. 将输入数据进行分割:将输入数据作为参数传入vtkLookupTable的MapScalars方法,将数据根据颜色表的分割规则进行分割,生成对应的颜色值。 通过上述步骤,就可以使用vtkLookupTable对输入数据进行分割,并且生成对应的颜色表示。这样可以直观地展示数据的分布情况,帮助用户更好地理解和分析数据。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值