You reinstalled the vision software stack, and now every save fails: imgSessionSaveBufferEx and ImaqArrayToImage return a no-size-info error on buffers that still display perfectly through imgGrab and imgPlot. The camera is fine and the buffer holds a complete frame; what broke is the description of the buffer. A reinstall restores default acquisition settings, so the pixel format the session now negotiates no longer matches the 3-bytes-per-pixel RGB layout your save code assumes. This guide gives the diagnosis in order of probability, the byte arithmetic for every packed format you will meet, one worked example, and the conversion sequence that restores saving.
The error names the description, not the pixels
A buffer is a block of memory. It has no inherent width, height or pixel format — those are attributes the acquisition layer attaches when it configures the session, and the saving calls demand them: imgSessionSaveBufferEx will not write a file without them, and ImaqArrayToImage will not build an image, which is why both fail with the same text while the frame itself is intact.
A driver reinstall is the classic trigger, and it fits this case exactly. The reinstall resets the acquisition configuration, the session negotiates a different format than the code was written against, and buffers created afterward carry attributes that no longer describe what the save path expects. Commit to this diagnosis first — a configuration reset changed the format — because it explains why every program failed at once, archived ones included. The code did not change; the configuration did.
Why display works while saving fails
imgGrab hands you a pointer into the ring buffer, and imgPlot draws pixels through the session, which knows its own live attributes; neither call ever has to describe the buffer on its own. Saving is different: the file writer must state rows, columns and bytes per pixel before it copies anything. That is the entire difference between the calls that work and the calls that fail. Image bytes vs pixel data: decode before processing walks the same split from the processing side.
Run a display-only loop first. If frames appear on screen, the pixels, the cable and the grabber are fine — stop debugging hardware and fix the description.
The byte math of each format
A single-sensor color camera does not send three bytes per pixel. A Bayer mosaic sits over the sensor, so each pixel carries one filtered sample — red, green or blue — at the sensor's native 10 or 12 bits, and three-value color exists only after demosaicing. The acquisition can therefore deliver a 10-bit frame from a color camera, and code that assumes 24-bit RGB from the start is describing a buffer that was never allocated.
Packing then removes the padding. Unpacked, each 10-bit pixel rides in a 16-bit word at 2 bytes per pixel. Packed, four 10-bit pixels share five bytes, and 12-bit data packs two pixels into three bytes. That is where whole-number bytes per pixel disappears — and with it, any width-times-depth multiplication a save call can check.
| Camera output | Bits per pixel | Bytes per pixel | Bytes in a 4000 px row |
|---|---|---|---|
| 8-bit monochrome | 8 | 1 | 4,000 |
| 10-bit, unpacked | 10 in a 16-bit word | 2 | 8,000 |
| 10-bit, packed | 10 | 1.25 (4 px per 5 B) | 5,000 |
| 12-bit, packed | 12 | 1.5 (2 px per 3 B) | 6,000 |
| RGB888 after demosaicing | 24 | 3 | 12,000 |
Read the table as the rule. Formats at 1, 2 or 3 bytes per pixel can be described to a save call directly; 1.25 and 1.5 cannot, because no whole bytes-per-pixel value reproduces the row length. Convert those before saving — packed Bayer 12-bit conversion to a 16-bit image is the same procedure at 12 bits.
Worked example: saving a 4000 × 3000 frame at 10 bits per pixel
Inputs, each with its source:
- Width 4000 px, height 3000 px — the full frame of a 12 MP sensor, the resolution printed for the LS-CMR-0166.
- 10 bits per pixel, packed Bayer — the camera's native color output, four pixels per five bytes.
- Save target: an uncompressed 8-bit RGB file at 24 bits per pixel.
The rule in words: convert bits to row bytes first, multiply by the row count, then compare against what the save call would copy.
- Row: 4000 px × 10 bit/px ÷ 8 = 40,000 bit ÷ 8 = 5,000 B
- Buffer: 5,000 B × 3,000 rows = 15,000,000 B, about 15 MB
- Save expectation at RGB888: 4000 × 3000 × 3 B = 36,000,000 B
- Shortfall: 36,000,000 ÷ 15,000,000 = 2.4
The save call would read 2.4 times past the end of the buffer, and no width × bytes-per-pixel product in RGB terms equals a 5,000-byte row, so the size check rejects the description and reports it as missing. The decision this hands you: any source format whose bytes per pixel is not a whole number gets converted before saving, always; formats at 1, 2 or 3 bytes per pixel save directly once the attributes are attached.
The fix, in order of probability
- Prove the frame is intact with display-only acquisition (
imgGrabplusimgPlot). Frames on screen: the fault is in the description, so continue. No frames: you have an installation or hardware problem, and the rest of this list will not help yet. - Read the format the session reports. Query the session's bit-depth or pixel-type attribute while acquiring and write the answer down. A 10-bit or Bayer answer where you expected RGB confirms the first cause.
- Make both sides match. Either set the camera's output to the 8-bit color format your save path expects, or point the save path at the format the camera sends — on GigE Vision cameras that setting is the pixel format feature, and why the format is fixed and how to set it names where it lives. If you choose 8-bit at the camera, know the cost: why 10-bit sensors ship 8-bit images explains what is discarded, and saving 12-bit camera images without losing intensity data shows the keep-the-bits route.
- Re-create the buffers. Buffers allocated under the old format keep the old, or absent, attributes; free and reallocate after every format change, because a save into a stale buffer fails identically.
- Convert packed data when you keep it: unpack to 16-bit planes first, then demosaic to RGB888. Access 10-bit RGB camera data: unpack to 16-bit planes first shows the unpack step, and the same order holds at save time. Once unpacked, every pixel is one 2-byte word and rows are simple again — locating image coordinates from a 2D pixel array works from exactly that layout.
- Prove it with a file: save one frame uncompressed and compare its size with width × height × bytes per pixel plus a small header. A number in the right order of magnitude closes the case.
When the format matches and the error stays
Two leftovers. First the converter: if you convert to a color image and then save, the converter's output type must match what the saver reads — a doubled or shifted color frame is the signature, and colour frame comes out doubled: fix the Mat type mismatch works that case end to end.
Second the installation: open the camera in the vendor's own acquisition tool. If that tool fails as well, your code is innocent — reinstall the driver package from the vendor's documented download, and when the error names a camera-description file (an .icd file, for example), replace it from that package rather than editing it.
Hardware that keeps saving simple
Every current camera in area scan cameras lets you lock the output format at startup through a standard interface, so a reinstall cannot silently change the layout — on GigE Vision models, why a GigE camera shows no color image shows the default you inherit when you do not. Decide by what the saved frames are for. Record images only: lock an 8-bit color output and save directly. Measurement frames: keep the 10- or 12-bit packed output, budget the unpack step, and save converted copies.
The MV-CU020-90GC is a 2.5 MP color camera with a global shutter on GigE.
- Sensor format
- 1/1.7"
- Lens mount
- C-mount
- Interface
- GigE
- Resolution
- Up to 3 MP
For larger fields, the MV-CS200-10GC is a 20 MP color camera on GigE, built around the IMX183 sensor.
- Sensor format
- 1"
- Lens mount
- C-mount
- Interface
- GigE
- Resolution
- 16-25 MP
If you drop to a binned or windowed format for simpler byte math, confirm the sensor still delivers the pixels your measurement needs — the camera resolution calculator settles that before you order, and the camera finder filters by sensor and interface.
The configurator matches a camera, lens, light, light controller and cables to each other, step by step, and lists only parts that fit what you already picked.
Checklist before the next save
- Read the session's reported pixel format before writing save code; it is the layout the code must match.
- Compute row bytes as width × bits ÷ 8 and compare with the buffer size the driver reports; a gap near 2× points at packing.
- Treat 1.25 and 1.5 bytes per pixel as convert-first formats.
- Set the format in code at startup, never only in a driver configuration a reinstall can reset.
- Re-create buffers after every format change.
- Check one uncompressed save against width × height × bytes per pixel plus header.
If the error survives a clean reinstall and a format-matched save path, send the format string the session reports and one failing frame through the contact page and we will size the conversion with you.
Questions
Why can imgGrab display the frame while imgSessionSaveBufferEx fails?
The display path renders through the acquisition session, which holds the live pixel-format attributes, so it never has to ask the buffer for its size. The save path serializes the buffer on its own and needs size info attached to that specific buffer. After a driver reinstall the attributes stamped onto newly created buffers are missing or stale, so display keeps working while every save and array conversion fails. Re-creating the buffers after setting the format restores them.
How many bytes per pixel does packed 10-bit color data really use?
1.25 bytes per pixel: four pixels share five bytes, so 40 bits of image become 5 bytes. A 4000-pixel row is therefore 5,000 bytes, not the 12,000 bytes of RGB888. Because 1.25 is not a whole number, code that multiplies width by a fixed 3 bytes per pixel cannot describe the buffer, which is exactly what the size check catches. Twelve-bit packed data runs at 1.5 bytes per pixel, two pixels in three bytes.
Should I just switch the camera to 8-bit output to make saving work?
Commit to that only when the saved frames are records, not measurements. Set the camera to an 8-bit color output, re-create the buffers, and the save call works with plain 3 bytes per pixel. If your inspection thresholds use the extra dynamic range of 10- or 12-bit data, keep the packed format and unpack to 16-bit before converting to color, because dropping to 8 bits at the camera throws that range away permanently.
Why does a color camera output only one value per pixel?
A single-sensor color camera has a Bayer mosaic over its pixels: each pixel measures one filtered color — red, green or blue — at 10 or 12 bits. Full RGB with three values per pixel exists only after demosaicing, on the PC or inside the camera. That is how the acquisition can grab a 10-bit frame from a color camera at 1.25 bytes per pixel, and why a 24-bit RGB assumption about that frame is wrong.
What file size proves the save is correct?
For an uncompressed format, expect width × height × bytes per pixel plus a small header. The 4000 × 3000 example gives 36,000,000 bytes as RGB888 and 15,000,000 bytes as 10-bit packed Bayer. PNG and JPEG compress below those numbers, so compare orders of magnitude, not exact bytes: a file near one third of the expected size says the saving call wrote one plane instead of three.

