Image Watch

Microsoft Free

Provides a watch window for visualizing in-memory images (bitmaps) when debugging native C++ code.

(26) Review
Visual Studio
2013, 2012
Download (21,155)
E-mail Twitter Digg Facebook
Add to favorites
Reviews (26)
Q and A (58)
Sign in to write a review
Sort by:

by John Dance | Fri 7:01 PM

This makes debugging image handling so much easier. I love it! Thank you! The ability to extend to my image types (QImage/QPixmap) is a game changer.

by Rob42_ | August 04 2014

Thanks for this great extension to Visual Studio,
would like to see this open sourced to add even more features.

by Mudit Agrawal | June 24 2014

This is indeed a game changer! Debugging in-memory images has always been so hard in VS. The simple power of Image-Watch visualization, combined with the efficient operators can turn hours of debugging to minutes or seconds.

Great work!

by lin jingxian | April 06 2014

sounds good, but can not use with vs 2013 express ?

by V.N.V | February 23 2014

Just a note to say a simple Thank You to the author.

This extension is excellent.

It provides a "quicklook" into a sequence of images from a loop.

Without it, I'd be spending much more time on the problem. I'd need to save each image to disk, with a serialized name,
and bring each up individually in an external viewer.

by Daehoe Kim | January 28 2014

Excellent tool. I love it :)

by Chris Sienkiewicz | December 26 2013

Fantastic add in, makes working with images so much easier.

by Akhil Prem | November 19 2013

Very handy when working with images. I love it that I can use it with custom image types using NatVis.

by Trass3r | November 14 2013

This is a lifesaver!

by sarthakpati | October 01 2013

by LevonGn | September 26 2013

by Alessandro R Silva | September 07 2013

This is one of the reasons why i develop in Windows in openCV. A Extraordinary tool, with no match.

by Son D Tran | August 30 2013

by Brian Catlin | August 11 2013

This awesome tool makes developing OpenCV programs a breeze!

by stocastico | August 07 2013

Excellent tool, highly recommended

by Mahesh.Nalam | July 17 2013

This is Very useful tool

by Eric Stollnitz | July 08 2013

This is an excellent tool for viewing images while debugging. Saved me tons of time!

by The Great Fox | June 21 2013

It's an awesome tool for debugging.

You should add Zoom In/Out and Pan though - it would really help when debugging large Font texture-atlases. You want to be able to zoom in the 128x512 bitmap and see how it looks.

Great work! :)

by knauer0x | June 21 2013

Nice tool!

by Arkady Shapkin | June 18 2013

1 - 20 of 26 Items   
Sign in to start a discussion

    9 Posts | Last post 2:46 AM
    • Hi,
      I have a image class with protected width, height & data. They are all accessible via member functions. Is there a way to write the .natvis file so that the image can be displayed correctly during debugging?
    • Hi Alexanderwyx, the debugger has access to all data members regardless of their access specifiers (public/protected/private). In other words, you can access your data members in the natvis as if they were public. Is that what you meant?
    • I have quite similar question to one Alexanderwyx asked. I'd like to display a QImage instance from the Qt 5 library (see for ref.) and an access to necessary data is only through member functions: width(), height(), bits() etc. Both the @mem operator and the .natvis file need member variables which in this case is problematic. Can you implement such a feature in the next release?
    • Hi Franc, 
      looking at the Qt 5 implementation I believe you should be able to visualize QImage objects with the current version of ImageWatch. QImage has a data member "d" which is a pointer to a QImageData object. QImageData has data members called "width", "height", "bytes_per_line", "format", and "data". QImage::width() simply returns d->width, so you should be able to do the same in your natvis (see example below). For pixel format, you can query QImageData's "format" member using the "Condition" attribute in the natvis. 
      So here's how I think your natvis could work. This example supports ARGB32 (5) and RGB888 (13) formats; you can add more, of course. Plase note that there could be errors, since I don't have a Qt build environment and couldn't test it.
      <Item Name="[width]">d->width</Item>. 
      <Item Name="[height]">d->height</Item>. 
      <Item Name="[stride]">d->bytes_per_line</Item>. 
      <Synthetic Name="[type]" Condition="d->format==5">
      <Synthetic Name="[type]" Condition="d->format==13">
      <Synthetic Name="[channels]" Condition="d->format==5">
      <Synthetic Name="[channels]" Condition="d->format==13">
      Please let me know if this solves your problem. 
    • Re-reading my reply I realized the "[data]" item is missing in my example natvis:
      <Item Name="[data]">d->data</Item>
    • Thank you Wolf for the hint. It looks like the "d" data member of QImage class is an opaque pointer and in order to force VS "see" QImageData members I must include a private header of QImage (QtGui\5.0.2\QtGui\private\qimage_p.h). Then finally Image Watch works with QImage.
      The problem is with a monochrome image where the image is stored using 1 bit per pixel. A part of d->data (a row the image) indicated by d->bytes_per_line almost always contains some rubbish at the end because the data chunk rounds to bytes. Do you have any idea how to cope with this?
    • Hi Franc, 
      great to hear that QImage works now! Thanks for pointing out the privateness of qimage_p.h. I hadn't noticed that. It's a little awkward, of course, to have to include that header, but I hope the better debugging experience makes up for it :) 
      I can see the problem with 1-bit-per-pixel formats (QImage::Format_Mono?). Unfortunately, there's no good workaround with the current version of Image Watch, since we don't support non-integer strides. Sorry..
    • Hi Wolf:
      I just found ImageWatch and love it. Thank you. Others might be interested in supporting QImage/QPixmap without adding a private header into their build. I cannot do that. Here is a definition for QImage that will work without the private header for all the 32bpp formats: 
        <Type Name="QImage">
            <Synthetic Name="[type]">
            <Synthetic Name="[channels]" Condition="(*(int*)(((char*)d)+48))==4">
            <Synthetic Name="[channels]" Condition="(*(int*)(((char*)d)+48))==5">
            <Synthetic Name="[channels]" Condition="(*(int*)(((char*)d)+48))==6">
            <Item Name="[width]">((Qt5Guid.dll!QImageData*)d)->width</Item>
            <Item Name="[height]">((Qt5Guid.dll!QImageData*)d)->height</Item>
            <Item Name="[depth]">((Qt5Guid.dll!QImageData*)d)->depth</Item>
            <Item Name="[nbytes]">((Qt5Guid.dll!QImageData*)d)->nbytes</Item>
            <Item Name="[devicePixelRatio]">((Qt5Guid.dll!QImageData*)d)->devicePixelRatio</Item>
            <Item Name="[data]">((Qt5Guid.dll!QImageData*)d)->data</Item>
            <Item Name="[stride]">((Qt5Guid.dll!QImageData*)d)->bytes_per_line</Item>
      If you always assume raster QPixmap objects, then you can also make a definition for QPixmap. Here is a sample entry for width:
            <Item Name="[width]">((Qt5Guid.dll!QImageData*)(((Qt5Guid.dll!QRasterPlatformPixmap*)(data.d))->image.d))->width</Item>
    • Hi John, 
      thanks a lot for your feedback and for sharing the visualizer!
  • Lambda functions
    3 Posts | Last post September 09, 2014
    • Are there any plans to enable evaluation of lambda functions in debugger/Image Watch? It would be very handy to define simple lambda functions that capture current context and call them from image watch.
      This question is probably not only related to the Image Watch tool but also to the Visual Studio debugger in general. Any comments on this would be helpful. Thank you.
    • Hi Zdenek,
      having lambdas would be handy, but we haven't planned it at the moment. Unfortunately, I don't have insight into the Visual Studio debugger team's plans, either. Sorry :/
      That said, we are currently working on a slightly solution for debugging scenarios like the one you described ... so stay tuned :)
    • sorry, typo: I meant to say: "slightly different" :)
  • Lambda functions
    1 Posts | Last post August 31, 2014
    • Are there any plans to enable evaluation of lambda functions in debugger/Image Watch? It would be very handy to define simple lambda functions that capture current context and call them from image watch.
      This question is probably not only related to the Image Watch tool but also to the Visual Studio debugger in general. Any comments on this would be helpful. Thank you.
  • Debugging slow with 4k x 3k images?
    3 Posts | Last post August 04, 2014
    • I've been using Image Watch since its release with images like 640 x 480, 1280 x 720 and similar, and never had any problems. More recently, I'm working with images that are 4320 x 3240 and similar, and the debugging is very slow. Stepping from one line to the next takes around 0.5 to 1 second, even if the image is not modified at all.
      Is something wrong with my system or is it a current limitation of Image Watch?
    • Hi Elador,
      there is nothing wrong with your system. 
      Here's why it is slow. The debugger has no way of knowing whether a block of memory in your app is modified when you step over a line of code. That's why it needs to make a fresh copy of *all* the pixels that you're viewing in Image Watch after *every* step. This simply takes longer if you have large images. 
      Image Watch is trying to be smart about this, though. It only reloads the pixels for the images you can actually see, either in the viewer area or as thumbnails in the image list. So, if you have no image selected for viewing, and if you collapse the image list so that you don't see the thumbnails (right click -> collapse all), then single stepping should be much faster. Another way to do this is to keep the Watch list empty and switch between Locals/Watch depending on whether you want to see pixels or not during your debugging session.
      Hope that helps!
    • Hi Wolf,
      That sounds reasonable. Good to know. Thank you very much for your suggestions - either going to an empty Watch-window or collapsing the images works great!
      Thank you!
  • Assertion Error
    3 Posts | Last post July 30, 2014
    • Hi.
      When I create the image with the size(1,65536), a problem of assertion error comes up in invalid image info. After I closed the this window, this problem did not come up. I think that image size is exceeded defined size.
      What's the maximum size used to image watch?
      If it wasn't for image size, what's the problem?
    • Hi Stacy, 
      thanks a lot for reporting this. Yes, the maximum size is 65535. The assertion window should not show, however. That's a bug. We'll have that fixed in the next release. We may increase the maximum image size, too :). 
      Thanks again!
    • I would also profit from larger supported image sizes. I have matrices that are around sizes like 80000 x 120 and it would be a great help to be able to see them. At the moment I always have to insert "debug-code" that extracts smaller submatrices to be able to view them.
  • Showing [invalid]
    3 Posts | Last post July 24, 2014
    • Hi, 
      First of all thanks a lot for this great tool. It makes our life much easier!
      I am trying to play with user-defined image type as part of project use user-defined image. 
      My image type is:
      struct IVC_DBIMG{
          int ncols;
          int nrows;
          int minx;
          int miny;
          int maxx;
          int maxy;
          double *data;
      } ;
      When I put the variable into Visual studio watch, I can see the channels=1, type=FLOAT64 and width, height and stride are the same as the variable I declared. 
      However, when I add the variable into ImageWatch, it shows it's invalid. [invalid] is shown on the snapshot and two [invalid]s are showing on the side. Here is the definition file:
        <Type Name="IVC_DBIMG">
          <UIVisualizer ServiceId="{A452AFEA-3DF6-46BB-9177-C0B08F318025}" Id="1" />
        <Type Name="IVC_DBIMG">
            <Synthetic Name="[type]">
            <Item Name="[channels]">1</Item>
            <Item Name="[width]">ncols</Item>
            <Item Name="[height]">nrows</Item>
            <Item Name="[data]">data</Item>
            <Item Name="[stride]">ncols</Item>
      I am using VS2012. The ImageWatch.log file shows that the IVC_DBIMG type is detected and added. 
      Can anyone provide tips on what might go wrong here?
      Thanks a lot in advance. 
    • The [stride] should be in bytes, so in your case 8*ncols
    • Matt,
      Thanks a lot. It works now!!! :)
  • Extension name was misleading
    2 Posts | Last post May 30, 2014
    • Reading the description of this extension I thought ... "oh, I sure missed something, I'll try".
      Now I know, I didn't miss something - in the description!
      But I miss something while using Image Watch! The support for build in types, like HBITMAP, HICON, HIMAGELIST.
      Why not supporting such handles to bitmaps in Image Watch?
      Best regards,
    • Thanks for your feedback, Martin. 
      I agree it would be nice to be able to see HICONs etc in Image Watch. The reason why we haven't done this yet is that Image Watch needs to know the internal data structures behind those handles, but those are not public. Of course, working at Microsoft, we could get this information and put it in Image Watch. But this means Image Watch would now have to track which Windows version (existing and future) uses which internal data layout. This is not feasible given our limited resources for the project. Sorry. :/
  • exception has been thrown by the target of an invocation
    2 Posts | Last post May 02, 2014
    • when i start the Image Watch an error throwed "exception has  been thrown by the target of an invocation". 
      I have uncheced Managed C++ Compatibility Mode.
      My vs version is 2013, i have updated with update 1 package .
    • Which process is throwing the exception, your app or Visual Studio?
  • Can I use vs2013?
    4 Posts | Last post April 30, 2014
    • Can I use vs2013? 
      I am using vs2013 to "[invalid]" has been output.
      Below is a sample code.
      struct My8BitRGBImage
      	unsigned int ncols;
      	unsigned int nrows;
      	unsigned char* data;
        <Type Name="My8BitRGBImage">
          <UIVisualizer ServiceId="{A452AFEA-3DF6-46BB-9177-C0B08F318025}" Id="1" />
        <Type Name="My8BitRGBImage">
            <Synthetic Name="[type]">
            <Synthetic Name="[channels]">
            <Item Name="[width]">ncols</Item>
            <Item Name="[height]">nrows</Item>
            <Item Name="[data]">data</Item>
            <Item Name="[stride]">ncols*3</Item>
    • and i am unchecked Use Managed Compatibility Mode in debug option
    • ye.. Solved
    • i have the same problem with you ,could you tell me how you sloved it.thank u . 
  • diagnostics
    5 Posts | Last post April 17, 2014
    • Is it possible to have error diagnostics? Either in the watch window itself or in the debug output together with the other natvis messages.
      It's really hard to tell why it doesn't display the image based on "[invalid]".
    • Hi Trass3r, thanks for the feedback. We've noticed that, too, and it's on our list. 
      In the meantime, I find it easiest to debug a natvis in two steps:
      First, disregard Image Watch and just look at the built-in Locals/Autos/Watch window. If you don't see your natvis items there ("[width]", for example), you have a bug in your natvis. That bug is unrelated to Image Watch and can be investigated using Visual Studio's built-in natvis diagnostics. 
      Then, once the natvis is working, it should be fairly straightforward to see why Image Watch shows "[invalid]".
      Hope that helps. Good luck! -Wolf
    • Everything is fine. And a manual '@mem(img.m_storage.m_data,FLOAT32,1,16,16,64)' works.
      <Item Name="[channels]">1</Item>
      <Item Name="[width]">m_storage.m_cols</Item>
      <Item Name="[height]">m_storage.m_rows</Item>
      <Item Name="[data]">m_storage.m_data</Item>
      <Item Name="[stride]">m_storage.m_cols * sizeof($T1)</Item>
      [type]	FLOAT32	
      [channels]	1	int
      [width]	16	unsigned __int64
      [height]	16	unsigned __int64
      [data]	0x000000000030d960	void *
      [stride]	64	unsigned __int64
      I also tried various casts cause I think a had a problem with the types before.
      But nothing happens.
    • Any ideas?
    • Hey Trass3r--sorry for the delay. Are debugging in mixed-mode? Also, would you mind providing a repro (C++ type definition + natvis)? Thanks!
1 - 10 of 58 Items