# Changing dimensions and number of scalar components for vtkImageData

**URL:** https://discourse.vtk.org/t/changing-dimensions-and-number-of-scalar-components-for-vtkimagedata/10550
**Category:** Support
**Created:** [January 28, 2023, 12:23pm UTC](https://discourse.vtk.org/t/changing-dimensions-and-number-of-scalar-components-for-vtkimagedata/10550 "2023-01-28T12:23:34Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![kit](https://discourse.vtk.org/letter_avatar_proxy/v4/letter/k/9fc29f/32.png) [@kit](https://discourse.vtk.org/u/kit)
#### Post date: [January 28, 2023, 12:23pm UTC](https://discourse.vtk.org/t/changing-dimensions-and-number-of-scalar-components-for-vtkimagedata/10550/1 "2023-01-28T12:23:34Z")

</div>

Hi All,

I have vtkImageData object with dimensions (nx,ny,nz) with 1 scalar component, but for various reasons, I’d like to be able to work on it as a vtkImageData with dimensions (ny,nz,1) and nx scalar components without having the reallocate and copy the entire structure. So essentially what I am looking for is a way to ShallowCopy the structure and then assign it different grid dimensions and a number of components.

Has anyone done this before? So far I can change the grid dimensions, but when I try to change the number of scalar components (image-\>GetPointData()-\>GetScalars()-\>SetNumberOfComponents()). It will still change the original object.

Thanks

---

<div class="post-metadata">

### Author: ![dgobbi](https://discourse.vtk.org/user_avatar/discourse.vtk.org/dgobbi/32/18_2.png) [@dgobbi](https://discourse.vtk.org/u/dgobbi)
#### Post date: [January 28, 2023, 1:22pm UTC](https://discourse.vtk.org/t/changing-dimensions-and-number-of-scalar-components-for-vtkimagedata/10550/2 "2023-01-28T13:22:15Z")

</div>

I don’t think that VTK provides any documented way of doing this. But you can try doing things in a specific order so that VTK doesn’t reallocate the array:

```cpp
vtkDataArray* a image->GetPointData()->GetScalars();
// shrink the array and hope underlying memory won't change
a->SetNumberOfTuples(1);
// set the desired number of components
a->SetNumberOfComponents(nx);
// set the new size
a->SetNumberOfTuples(ny * nz);

```

This code assumes that VTK will not reallocate the memory if the new size fits within the old size.

---

<div class="post-metadata">

### Author: ![kit](https://discourse.vtk.org/letter_avatar_proxy/v4/letter/k/9fc29f/32.png) [@kit](https://discourse.vtk.org/u/kit)
#### Post date: [January 28, 2023, 2:11pm UTC](https://discourse.vtk.org/t/changing-dimensions-and-number-of-scalar-components-for-vtkimagedata/10550/3 "2023-01-28T14:11:40Z")

</div>

Thanks David,

I tried the following, but the issue is that the number of scalar components in the original object is changed, presumably because the ShallowCopy just copies the reference pointer to the data array, rather than separating data and metadata.

Let me know what you think

```auto
vtkSmartPointer<vtkImageData> image1 = vtkSmartPointer<vtkImageData>::New();
image1->SetDimensions(5, 5, 5);
image1->AllocateScalars(VTK_FLOAT, 1);

{
  int* dims = image1->GetDimensions();
 
  // Gives 125
  cout << "\nImage 1 number of points = " << image1->GetNumberOfPoints() << endl;
  
  // gives 5,5,5
  cout << "Image 1 dimensions =" << dims[0] << ", " << dims[1] << ", " << dims[2] << endl;
  
  // Gives 1
  cout << "Image 1 number of scalar components = " << image1->GetNumberOfScalarComponents() << endl;
}

// Shallow copy and change the dimensions
vtkSmartPointer<vtkImageData> image2=vtkSmartPointer<vtkImageData>::New();
image2->ShallowCopy(image1);
image2->SetDimensions(5, 5, 1);

vtkDataArray* arr=image2->GetPointData()->GetScalars();
arr->SetNumberOfTuples(1);
arr->SetNumberOfComponents(5);
arr->SetNumberOfTuples(5*5);

{
  int* dims = image2->GetDimensions();
  
  // This correctly gives 25
  cout << "\nImage 2 number of points = " << image2->GetNumberOfPoints() << endl;
  
  // this correctly gives 5,5,1
  cout << "Image 2 dimensions =" << dims[0] << ", " << dims[1] << ", " << dims[2] << endl;
  
  // This correctly gives 5
  cout << "Image 2 number of scalar components = " << image2->GetNumberOfScalarComponents() << endl;
}

// But the number of scalar components for image1 have also changed.
{
  int* dims = image1->GetDimensions();
  
  // This correctly gives 125
  cout << "\nImage 1 number of points = " << image1->GetNumberOfPoints() << endl;
  
  // This correctly gives 5,5,5
  cout << "Image 1 dimensions =" << dims[0] << ", " << dims[1] << ", " << dims[2] << endl;
  
  // This gives 5 but should be 1
  cout << "Image 1 number of scalar components = " << image1->GetNumberOfScalarComponents() << endl;
}

```

---

<div class="post-metadata">

### Author: ![lassoan](https://discourse.vtk.org/user_avatar/discourse.vtk.org/lassoan/32/50_2.png) [@lassoan](https://discourse.vtk.org/u/lassoan)
#### Post date: [January 28, 2023, 4:03pm UTC](https://discourse.vtk.org/t/changing-dimensions-and-number-of-scalar-components-for-vtkimagedata/10550/4 "2023-01-28T16:03:41Z")

</div>

You can use `vtkImageImport` on the memory pointer of the original image to reuse the memory area in another image.

Note that VTK supports different memory layouts, so this is not a robust or clean solution, but if you always obtain the original image the same way then most likely it will always behave the same way. It also breaks the update request propagation chain, so if a filter before the image import is changed then you need to update the filter output manually.

The clean solution would be just to not do this. You are probably forcing an import, export, or processing filter to do something that it is not supposed to do. If you have a valid reason to do this (e.g., an importer incorrectly reads a color 2D image as a 3D scalar image) then that should be fixed/improved in the affected filters.

---

<div class="post-metadata">

### Author: ![dgobbi](https://discourse.vtk.org/user_avatar/discourse.vtk.org/dgobbi/32/18_2.png) [@dgobbi](https://discourse.vtk.org/u/dgobbi)
#### Post date: [January 28, 2023, 4:04pm UTC](https://discourse.vtk.org/t/changing-dimensions-and-number-of-scalar-components-for-vtkimagedata/10550/5 "2023-01-28T16:04:02Z")

</div>

For the new image, you can make a new array that points to the same memory as the old array. Then you can adjust the size of this new array, and the old array will stay as-is.

```cpp
vtkNew<vtkFloatArray> b;
vtkFloatArray* a = vtkFloatArray::SafeDownCast(image1->GetPointData()->GetScalars());
if (a != nullptr)
{
    b->SetName(a->GetName());
    b->SetNumberOfComponents(nx);
    b->SetArray(a->GetPointer(0), ny*nz, 1);
    image2->GetPointData()->SetScalars(b);
}

```

(Note: I wrote this code off the top of my head so it’s likely to contain mistakes).

Note that if the first array is resized, destroyed, etc. then the memory in the second array becomes invalid, since they’re sharing the same block of memory. VTK does not provide a safe way for arrays to share memory.

---

<div class="post-metadata">

### Author: ![kit](https://discourse.vtk.org/letter_avatar_proxy/v4/letter/k/9fc29f/32.png) [@kit](https://discourse.vtk.org/u/kit)
#### Post date: [January 28, 2023, 5:05pm UTC](https://discourse.vtk.org/t/changing-dimensions-and-number-of-scalar-components-for-vtkimagedata/10550/6 "2023-01-28T17:05:53Z")

</div>

That works, thanks. It is good to know about vtkImageImport as well.

---

<div class="post-metadata">

### Author: ![kit](https://discourse.vtk.org/letter_avatar_proxy/v4/letter/k/9fc29f/32.png) [@kit](https://discourse.vtk.org/u/kit)
#### Post date: [January 31, 2023, 1:43pm UTC](https://discourse.vtk.org/t/changing-dimensions-and-number-of-scalar-components-for-vtkimagedata/10550/7 "2023-01-31T13:43:08Z")

</div>

Update, I ran into some issues where the MaxId for the scalar data was not being set for the new array. However, I got it working with the following

```auto
vtkNew<vtkFloatArray> b;
            vtkFloatArray* a = vtkFloatArray::SafeDownCast(pdo->GetPointData()->GetScalars());
            if (a != nullptr)
            {
                b->SetName(a->GetName());
                b->SetNumberOfComponents(nComponent);
                b->SetVoidArray(a->GetPointer(0), a->GetDataSize(), 1);
                this->GetPointData()->SetScalars(b);
                this->GetPointData()->SetActiveScalars(b->GetName());
            }else{
                return 0;
            }

```

So far so good for this as a soln…
