vtk显示2D序列图像

2018-09-04 16:50:45:记录一个很老很老的例子,2014年写的,存在这里,算是个见证。

一,显示XYZ三视图切面。

直接用VTK中的一个demo。
XYZ

class vtkSliderCallback : public vtkCommand
{
public:
    static vtkSliderCallback *New() 
    {
        return new vtkSliderCallback;
    }
    virtual void Execute(vtkObject *caller, unsigned long, void*)
    {
        vtkSliderWidget *sliderWidget = 
            reinterpret_cast<vtkSliderWidget*>(caller);
        if(!sliderWidget) return;
        int value = static_cast<int>(static_cast<vtkSliderRepresentation *>
            (sliderWidget->GetRepresentation())->GetValue());

        if ( this->WidgetX )
        {
            this->WidgetX->SetSliceIndex(value);
        }
        else if( this->WidgetY )
        {
            this->WidgetY->SetSliceIndex(value);
        }
        else if (this->WidgetZ)
        {
            this->WidgetZ->SetSliceIndex(value);
        }   
    }

    vtkSliderCallback():WidgetX( 0 ), WidgetY( 0 ), WidgetZ ( 0 ) {}

    vtkImagePlaneWidget* WidgetX;
    vtkImagePlaneWidget* WidgetY;
    vtkImagePlaneWidget* WidgetZ;
};

class vtkWidgetWindowLevelCallback : public vtkCommand
{
public:
    static vtkWidgetWindowLevelCallback *New()  
    { 
        return new vtkWidgetWindowLevelCallback; 
    }

    void Execute( vtkObject *caller, unsigned long vtkNotUsed( event ),
        void *callData )
    {
        vtkImagePlaneWidget* self =
            reinterpret_cast< vtkImagePlaneWidget* >( caller );
        if(!self) return;

        double* wl = static_cast<double*>( callData );

        if ( self == this->WidgetX )
        {
            this->WidgetY->SetWindowLevel(wl[0],wl[1]);
            this->WidgetZ->SetWindowLevel(wl[0],wl[1]);
        }
        else if( self == this->WidgetY )
        {
            this->WidgetX->SetWindowLevel(wl[0],wl[1]);
            this->WidgetZ->SetWindowLevel(wl[0],wl[1]);
        }
        else if (self == this->WidgetZ)
        {
            this->WidgetX->SetWindowLevel(wl[0],wl[1]);
            this->WidgetY->SetWindowLevel(wl[0],wl[1]);
        }
    }

    vtkWidgetWindowLevelCallback():WidgetX( 0 ), WidgetY( 0 ), WidgetZ ( 0 ) {}

    vtkImagePlaneWidget* WidgetX;
    vtkImagePlaneWidget* WidgetY;
    vtkImagePlaneWidget* WidgetZ;
};  

int main()
{
    ///文件读取的操作  
    vtkVolume16Reader* pReader =  vtkVolume16Reader::New();
    pReader->SetDataDimensions( 64, 64);
    pReader->SetDataByteOrderToLittleEndian();
    pReader->SetImageRange( 1, 93);
    pReader->SetDataSpacing( 3.2, 3.2, 1.5);
    pReader->SetFilePrefix( "D:\\VTKITK\\vtkdata-5.6.0\\Data\\headsq\\quarter" );
    pReader->SetDataMask( 0x7fff);
    pReader->Update();  

    vtkOutlineFilter *DicomOutline = vtkOutlineFilter::New();
    DicomOutline->SetInputConnection( pReader->GetOutputPort() );

    vtkPolyDataMapper *pMapper = vtkPolyDataMapper::New();
    pMapper->SetInputConnection( DicomOutline->GetOutputPort() );

    vtkActor *DicomActor = vtkActor::New();
    DicomActor->SetMapper( pMapper );   

    vtkRenderer *ren = vtkRenderer::New();
    vtkRenderer *ren1 = vtkRenderer::New();
    vtkRenderer *ren2 = vtkRenderer::New();
    vtkRenderer *ren3 = vtkRenderer::New();

    vtkRenderWindow *renWin = vtkRenderWindow::New();
    vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New(); 

    renWin->AddRenderer( ren1 );
    renWin->AddRenderer( ren2 );
    renWin->AddRenderer( ren3 );
    renWin->AddRenderer( ren );
    iren->SetRenderWindow(renWin);

    vtkCellPicker *picker = vtkCellPicker::New();
    picker->SetTolerance( 0.005 );

    vtkImagePlaneWidget *planeWidgetX = vtkImagePlaneWidget::New();
    planeWidgetX->SetInteractor( iren );
    planeWidgetX->SetKeyPressActivationValue( 'x' );
    planeWidgetX->SetPicker( picker );
    planeWidgetX->RestrictPlaneToVolumeOn();
    planeWidgetX->GetPlaneProperty()->SetColor( 0.0, 0.0, 1.0 );
    planeWidgetX->DisplayTextOn();
    //planeWidgetX->TextureInterpolateOn();
    planeWidgetX->TextureInterpolateOff();
    planeWidgetX->SetResliceInterpolateToLinear();
    planeWidgetX->SetInput( (vtkDataSet*)pReader->GetOutput() );
    planeWidgetX->SetPlaneOrientationToXAxes();//冠
    planeWidgetX->SetSliceIndex( 32 );
    planeWidgetX->GetTexturePlaneProperty()->SetOpacity( 1 );
    planeWidgetX->On(); 

    vtkImagePlaneWidget *planeWidgetY = vtkImagePlaneWidget::New();
    planeWidgetY->SetInteractor( iren );
    planeWidgetY->SetKeyPressActivationValue( 'y' );
    planeWidgetY->SetPicker( picker );
    planeWidgetY->RestrictPlaneToVolumeOn();
    planeWidgetY->GetPlaneProperty()->SetColor( 1.0, 0.0, 0.0 );
    planeWidgetY->DisplayTextOn();
    planeWidgetY->TextureInterpolateOn();
    planeWidgetY->SetResliceInterpolateToLinear();
    planeWidgetY->SetInput( (vtkDataSet*)pReader->GetOutput() );
    planeWidgetY->SetPlaneOrientationToYAxes();//矢
    planeWidgetY->SetSliceIndex( 25 );
    planeWidgetY->On();

    vtkImagePlaneWidget *planeWidgetZ = vtkImagePlaneWidget::New();
    planeWidgetZ->SetInteractor( iren );
    planeWidgetZ->DisplayTextOn();
    planeWidgetZ->RestrictPlaneToVolumeOn();
    planeWidgetZ->SetKeyPressActivationValue( 'z' );
    planeWidgetZ->SetPicker( picker );
    planeWidgetZ->GetPlaneProperty()->SetColor( 1.0, 1.0, 0.0 );
    planeWidgetZ->TextureInterpolateOn();
    planeWidgetZ->SetResliceInterpolateToLinear();
    planeWidgetZ->SetInput( (vtkDataSet*)pReader->GetOutput() );
    planeWidgetZ->SetPlaneOrientationToZAxes(); //横断面
    planeWidgetZ->SetSliceIndex( 50 );
    planeWidgetZ->On();

//////////////////////////////////////////////////////
    vtkWidgetWindowLevelCallback *cbk = vtkWidgetWindowLevelCallback::New();
    cbk->WidgetX = planeWidgetX;
    cbk->WidgetY = planeWidgetY;
    cbk->WidgetZ = planeWidgetZ;
    planeWidgetX->AddObserver( vtkCommand::EndWindowLevelEvent, cbk );
    planeWidgetY->AddObserver( vtkCommand::EndWindowLevelEvent, cbk );
    planeWidgetZ->AddObserver( vtkCommand::EndWindowLevelEvent, cbk );
    cbk->Delete();
//////////////////////////////////////////////////////
    vtkSliderRepresentation2D *sliderRep1 = vtkSliderRepresentation2D::New();
    sliderRep1->SetMinimumValue(1);
    sliderRep1->SetMaximumValue(50);
    sliderRep1->SetValue(planeWidgetX->GetSliceIndex());
    sliderRep1->GetPoint1Coordinate()->SetCoordinateSystemToNormalizedDisplay();
    sliderRep1->GetPoint1Coordinate()->SetValue(.0 ,.02);
    sliderRep1->GetPoint2Coordinate()->SetCoordinateSystemToNormalizedDisplay();
    sliderRep1->GetPoint2Coordinate()->SetValue(1.0, .02);  

    vtkSliderWidget *sliderWidget1= vtkSliderWidget::New();
    sliderWidget1->SetInteractor(iren);
    sliderWidget1->SetRepresentation(sliderRep1);
    sliderWidget1->SetAnimationModeToAnimate();
    sliderWidget1->EnabledOn();

    vtkSliderCallback  *slidercbk = vtkSliderCallback::New();
    slidercbk->WidgetX = planeWidgetX;
    sliderWidget1->AddObserver(vtkCommand::InteractionEvent,slidercbk);
//////////////////////////////////////////////////////
    //增加2D图像测试获取切片
    vtkImageMapToColors *colorMap1 = vtkImageMapToColors::New();
    colorMap1->PassAlphaToOutputOff(); //use in RGBA
    colorMap1->SetActiveComponent( 0 );
    colorMap1->SetOutputFormatToLuminance();
    colorMap1->SetInput( (vtkDataSet*)planeWidgetX->GetResliceOutput() );
    colorMap1->SetLookupTable( (vtkScalarsToColors *)planeWidgetX->GetLookupTable() );
    vtkImageActor *imageActor1 = vtkImageActor::New();
    imageActor1->PickableOff();
    imageActor1->SetInput( colorMap1->GetOutput() );

    vtkImageMapToColors *colorMap2 = vtkImageMapToColors::New();
    colorMap2->PassAlphaToOutputOff(); 
    colorMap2->SetActiveComponent( 0 ); // for muti-component
    colorMap2->SetOutputFormatToLuminance();
    colorMap2->SetInput( (vtkDataSet*)planeWidgetY->GetResliceOutput() );
    colorMap2->SetLookupTable( (vtkScalarsToColors *)planeWidgetX->GetLookupTable() );
    vtkImageActor *imageActor2 = vtkImageActor::New();
    imageActor2->PickableOff();
    imageActor2->SetInput( colorMap2->GetOutput() );

    vtkImageMapToColors *colorMap3 = vtkImageMapToColors::New();
    colorMap3->PassAlphaToOutputOff();
    colorMap3->SetActiveComponent( 0 );
    colorMap3->SetOutputFormatToLuminance();
    colorMap3->SetInput( (vtkDataSet*)planeWidgetZ->GetResliceOutput() );
    colorMap3->SetLookupTable( (vtkScalarsToColors *)planeWidgetX->GetLookupTable());
    vtkImageActor *imageActor3 = vtkImageActor::New();
    imageActor3->PickableOff();
    imageActor3->SetInput( colorMap3->GetOutput() );
/////////////////////////////////////////////////////////////////////
    vtkSmartPointer<vtkTransform> transform =
        vtkSmartPointer<vtkTransform>::New();
    transform->Translate(-10.0, -10.0, -10.0);

    vtkSmartPointer<vtkAxesActor> axes =
        vtkSmartPointer<vtkAxesActor>::New();

    axes->SetUserTransform(transform);

    ren->AddActor(axes);
//////////////////////////////////////////////////////

    ren->AddActor( DicomActor ); //outline
    ren1->AddActor( imageActor1 );
    ren2->AddActor( imageActor2 );
    ren3->AddActor( imageActor3 );

    // OK
    ren->SetBackground(  0.1, 0.1, 0.2 );
    ren1->SetBackground( 0.1, 0.2, 0.1 );
    ren2->SetBackground( 0.2, 0.1, 0.2 );
    ren3->SetBackground( 0.2, 0.2, 0.2 );

    renWin->SetSize( 600, 400 );
    //renWin->SetFullScreen(1);     

    ren3->SetViewport( 0, 0.5, 0.5, 1 );
    ren1->SetViewport( 0.5, 0.5, 1, 1 );
    ren2->SetViewport( 0, 0, 0.5, 0.5 );
    ren->SetViewport( 0.5, 0, 1, 0.5 );

    ren->GetActiveCamera()->Dolly(1.15);
    ren1->GetActiveCamera()->Dolly(1.15);
    ren2->GetActiveCamera()->Dolly(1.15);
    ren3->GetActiveCamera()->Dolly(1.15);

    ren->ResetCamera();
    ren1->ResetCamera();
    ren2->ResetCamera();
    ren3->ResetCamera();

    iren->Initialize();
    renWin->SetWindowName("vtkSuperViewer by winston");
    iren->Start();
    renWin->Render();

    return 0;
}

二,显示Z视图。

这个显示的方法是把vtkImagePlaneWidget不断的映射到vtkImageMapToColors上,其实是new了一个actor。我的需求是把vtkImagePlaneWidget改成一个新的Widget,只有一个面,保持原来的特性,但不能再切换的时候缩小。
Z

    class vtkSliderCallback : public vtkCommand
    {
    public:
     static vtkSliderCallback *New()
     {
      return new vtkSliderCallback;
     }
     virtual void Execute(vtkObject *caller, unsigned long, void*)
     {
      vtkSliderWidget *sliderWidget =
       reinterpret_cast<vtkSliderWidget*>(caller);
      if(!sliderWidget) return;
      int value = static_cast<int>(static_cast<vtkSliderRepresentation *>
       (sliderWidget->GetRepresentation())->GetValue());

      if ( this->WidgetX )
      {
       this->WidgetX->SetSliceIndex(value);
      }
      else if( this->WidgetY )
      {
       this->WidgetY->SetSliceIndex(value);
      }
      else if (this->WidgetZ)
      {
       this->WidgetZ->SetSliceIndex(value);
      }

     }

     vtkSliderCallback():WidgetX( 0 ), WidgetY( 0 ), WidgetZ ( 0 ) {}

     vtkImagePlaneWidget* WidgetX;
     vtkImagePlaneWidget* WidgetY;
     vtkImagePlaneWidget* WidgetZ;
    };

    class vtkWidgetWindowLevelCallback : public vtkCommand
    {
    public:
     static vtkWidgetWindowLevelCallback *New()

     {
      return new vtkWidgetWindowLevelCallback;
     }

     void Execute( vtkObject *caller, unsigned long vtkNotUsed( event ),
      void *callData )
     {
      vtkImagePlaneWidget* self =
       reinterpret_cast< vtkImagePlaneWidget* >( caller );
      if(!self) return;

      double* wl = static_cast<double*>( callData );

      if ( self == this->WidgetX )
      {
       this->WidgetY->SetWindowLevel(wl[0],wl[1]);
       this->WidgetZ->SetWindowLevel(wl[0],wl[1]);
      }
      else if( self == this->WidgetY )
      {
       this->WidgetX->SetWindowLevel(wl[0],wl[1]);
       this->WidgetZ->SetWindowLevel(wl[0],wl[1]);
      }
      else if (self == this->WidgetZ)
      {
       this->WidgetX->SetWindowLevel(wl[0],wl[1]);
       this->WidgetY->SetWindowLevel(wl[0],wl[1]);
      }
     }

     vtkWidgetWindowLevelCallback():WidgetX( 0 ), WidgetY( 0 ), WidgetZ ( 0 ) {}

     vtkImagePlaneWidget* WidgetX;
     vtkImagePlaneWidget* WidgetY;
     vtkImagePlaneWidget* WidgetZ;
    };  

    int main()
    {   
     vtkVolume16Reader* pReader = vtkVolume16Reader::New();
     pReader->SetDataDimensions( 64, 64);
     pReader->SetDataByteOrderToLittleEndian();
     pReader->SetImageRange( 1, 93);
     pReader->SetDataSpacing( 3.2, 3.2, 1.5);
     pReader->SetFilePrefix( "D:\\VTKITK\\VTK\\vtkdata-5.8.0\\Data\\headsq\\quarter" );
     pReader->SetDataMask( 0x7fff);
     pReader->Update(); 

     vtkRenderer *ren = vtkRenderer::New();
     vtkRenderWindow *renWin = vtkRenderWindow::New();
     vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New();
     vtkSmartPointer<vtkInteractorStyleImage> style = vtkSmartPointer<vtkInteractorStyleImage>::New();

     iren->SetInteractorStyle(style);
     ren->SetBackground( 0.0, 0.0, 0.4);
     renWin->AddRenderer( ren );
     iren->SetRenderWindow(renWin);

     vtkCellPicker *picker = vtkCellPicker::New();
     picker->SetTolerance( 0.005 );

     vtkProperty* ipwProp = vtkProperty::New();

     vtkImagePlaneWidget *planeWidgetZ = vtkImagePlaneWidget::New();
     //planeWidgetZ->SetInteractor( iren );
     planeWidgetZ->DisplayTextOn();
     planeWidgetZ->SetPicker( picker );
     planeWidgetZ->RestrictPlaneToVolumeOn();
     planeWidgetZ->GetPlaneProperty()->SetColor( 1.0, 1.0, 0.0 );
     planeWidgetZ->SetKeyPressActivationValue( 'z' );
     planeWidgetZ->SetTexturePlaneProperty(ipwProp);
     planeWidgetZ->SetResliceInterpolateToNearestNeighbour();
     planeWidgetZ->SetInput( (vtkDataSet*)pReader->GetOutput() );
     planeWidgetZ->SetPlaneOrientationToZAxes(); //横断面
     //planeWidgetZ->SetSliceIndex( 50 );
     //planeWidgetZ->On();

     //////////////////////////////////////////////////////
     vtkWidgetWindowLevelCallback *callback = vtkWidgetWindowLevelCallback::New();
     callback->WidgetZ = planeWidgetZ;
     planeWidgetZ->AddObserver( vtkCommand::EndWindowLevelEvent, callback );
     callback->Delete();
     //////////////////////////////////////////////////////
     vtkSliderRepresentation2D *sliderRep = vtkSliderRepresentation2D::New();
     sliderRep->SetMinimumValue(1);
     sliderRep->SetMaximumValue(50);
     sliderRep->SetValue(planeWidgetZ->GetSliceIndex());
     sliderRep->GetPoint1Coordinate()->SetCoordinateSystemToNormalizedDisplay();
     sliderRep->GetPoint1Coordinate()->SetValue(.0 ,.02);
     sliderRep->GetPoint2Coordinate()->SetCoordinateSystemToNormalizedDisplay();
     sliderRep->GetPoint2Coordinate()->SetValue(1.0, .02);

     vtkSliderWidget *sliderWidget= vtkSliderWidget::New();
     sliderWidget->SetInteractor(iren);
     sliderWidget->SetRepresentation(sliderRep);
     sliderWidget->SetAnimationModeToAnimate();
     sliderWidget->EnabledOn();

     vtkSliderCallback *slidercbk = vtkSliderCallback::New();
     slidercbk->WidgetX = planeWidgetZ;
     sliderWidget->AddObserver(vtkCommand::InteractionEvent,slidercbk);
     //////////////////////////////////////////////////////
     //增加2D图像测试获取切片
     vtkImageMapToColors *colorMap = vtkImageMapToColors::New();
     colorMap->PassAlphaToOutputOff();
     colorMap->SetActiveComponent( 0 );
     colorMap->SetOutputFormatToLuminance();
     colorMap->SetInput( (vtkDataSet*)planeWidgetZ->GetResliceOutput() );
     colorMap->SetLookupTable( (vtkScalarsToColors *)planeWidgetZ->GetLookupTable());

     vtkImageActor *imageActor = vtkImageActor::New();
     imageActor->PickableOff();
     imageActor->SetInput( colorMap->GetOutput() );

     ren->AddActor( imageActor );   
     // OK
     renWin->SetSize( 600, 400 );
     ren->ResetCamera();

     iren->Initialize();
     renWin->SetWindowName("vtkSuperViewer by winston");
     iren->Start();
     renWin->Render();  
     //return 0;
    }

三,vtkImagePlaneWidget 的一个切片

可以切换,但会有显示问题。大小会改变,这样不能自定义内容,看来只能自己写扩展类。
边框,十字叉,坐标取点,灰度取点,切片切换,窗宽窗位获取,窗宽窗位调节。
ZZZ

class vtkSliderCallback : public vtkCommand
{
public:
 static vtkSliderCallback *New()
 {
  return new vtkSliderCallback;
 }
 virtual void Execute(vtkObject *caller, unsigned long, void*)
 {

  vtkSliderWidget *sliderWidget =
   reinterpret_cast<vtkSliderWidget*>(caller);
  if(!sliderWidget) return;
  int value = static_cast<int>(static_cast<vtkSliderRepresentation *>
   (sliderWidget->GetRepresentation())->GetValue());

  if ( this->WidgetX )
  {
   this->WidgetX->SetSliceIndex(value);
  }
  else if( this->WidgetY )
  {
   this->WidgetY->SetSliceIndex(value);
  }
  else if (this->WidgetZ)
  {
   this->WidgetZ->SetSliceIndex(value);
  }
 }

 vtkSliderCallback():WidgetX( 0 ), WidgetY( 0 ), WidgetZ ( 0 ) {}

 vtkImagePlaneWidget* WidgetX;
 vtkImagePlaneWidget* WidgetY;
 vtkImagePlaneWidget* WidgetZ;
};

int main()
{   
 vtkVolume16Reader* pReader = vtkVolume16Reader::New();
 pReader->SetDataDimensions( 64, 64);
 pReader->SetDataByteOrderToLittleEndian();
 pReader->SetImageRange( 1, 93);
 pReader->SetDataSpacing( 3.2, 3.2, 1.5);
 pReader->SetFilePrefix( "D:\\VTKITK\\VTK\\vtkdata-5.8.0\\Data\\headsq\\quarter" );
 pReader->SetDataMask( 0x7fff);
 pReader->Update(); 

 vtkRenderer *ren = vtkRenderer::New();
 vtkRenderWindow *renWin = vtkRenderWindow::New();
 vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New();
 vtkSmartPointer<vtkInteractorStyleImage> style = vtkSmartPointer<vtkInteractorStyleImage>::New();

 iren->SetInteractorStyle(style);
 ren->SetBackground( 0.0, 0.0, 0.0);
 renWin->AddRenderer( ren );
 iren->SetRenderWindow(renWin);

 vtkCellPicker *picker = vtkCellPicker::New();
 picker->SetTolerance( 0.005 );

 vtkProperty* ipwProp = vtkProperty::New();

 vtkImagePlaneWidget *planeWidgetZ = vtkImagePlaneWidget::New();
 planeWidgetZ->SetInteractor( iren );
 planeWidgetZ->DisplayTextOn();
 planeWidgetZ->SetPicker( picker );
 planeWidgetZ->RestrictPlaneToVolumeOn();
 planeWidgetZ->GetPlaneProperty()->SetColor( 1.0, 1.0, 0.0 );
 planeWidgetZ->SetKeyPressActivationValue( 'z' );
 planeWidgetZ->SetTexturePlaneProperty(ipwProp);
 planeWidgetZ->SetResliceInterpolateToNearestNeighbour();
 planeWidgetZ->SetInput( (vtkDataSet*)pReader->GetOutput() );
 planeWidgetZ->SetPlaneOrientationToZAxes(); //横断面
 planeWidgetZ->SetSliceIndex( 50 );
 planeWidgetZ->On();

 //////////////////////////////////////////////////////
 vtkSliderRepresentation2D *sliderRep = vtkSliderRepresentation2D::New();
 sliderRep->SetMinimumValue(1);
 sliderRep->SetMaximumValue(50);
 sliderRep->SetValue(planeWidgetZ->GetSliceIndex());
 sliderRep->GetPoint1Coordinate()->SetCoordinateSystemToNormalizedDisplay();
 sliderRep->GetPoint1Coordinate()->SetValue(.0 ,.02);
 sliderRep->GetPoint2Coordinate()->SetCoordinateSystemToNormalizedDisplay();
 sliderRep->GetPoint2Coordinate()->SetValue(1.0, .02);

 vtkSliderWidget *sliderWidget= vtkSliderWidget::New();
 sliderWidget->SetInteractor(iren);
 sliderWidget->SetRepresentation(sliderRep);
 sliderWidget->SetAnimationModeToAnimate();
 sliderWidget->EnabledOn();

 vtkSliderCallback *slidercbk = vtkSliderCallback::New();
 slidercbk->WidgetZ = planeWidgetZ;
 sliderWidget->AddObserver(vtkCommand::InteractionEvent,slidercbk);

 // OK
 renWin->SetSize( 600, 400 );
 ren->ResetCamera();

 iren->Initialize();
 renWin->SetWindowName("vtkSuperViewer by winston");
 iren->Start();
 renWin->Render();  
 //return 0;
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值