Debugging image rendering in Visual C++, any helpf

2019-05-02 07:12发布

问题:

I often write code that renders images by writing pixels directly into buffers and I often find it hard to get a good overview of what's really going on. The Memory window in Visual Studio's debugger is somewhat a help, but I'd really love to see the images graphically.

So my question is, does anyone know of a debugging extension that can read a chunk of memory as a picture in a specified pixel format and display it graphically?

回答1:

Such a thing exists:

A utility for simple printf-style debugging of images in Win32 C/C++ applications.

http://billbaxter.com/projects/imdebug/

My coworker raves about it.

--chris



回答2:

A colleague of mine wrote this CodeProject article for writing Debugger Visualizers

http://www.codeproject.com/KB/showcase/BuildDebuggerVisualizer.aspx

It uses our product, a .NET imaging toolkit, but it could easily be adapted to use .NET image classes instead.



回答3:

What you're asking for is not naturally achieveable in native c++. All the visualization technology inside the visual debugger is organized around the CLR, hence either C# or C++/CLI.

The one thing that can help in native land is the expression evaluator addin mechanism. Of course, it's designed to return a string and go away, but it's code, so you could in theory run any code, including displaying a window and showing the data you care about (after having read it from the debuggee).

It's a bit of a bummer to see those great features missing from the native side, though.



回答4:

I'm developing a open source Add-In, Visual Image Assist, for VC6/7/8/9 used to show/edit a image. It may be you want, too.



回答5:

  1. Create a class containing your buffer + metadata (width, height, stride, pixelformat).
  2. Add ToStream() and FromStream() methods to your class for (de)serializing image (buffer and metadata).
  3. Add a ToWpfBitmapSource() to your class.
  4. Create a debug visualizer that deserializes your image from the stream, converts to WPF's BitmapSource, places in an Image control, within a Winforms WPF host.

This example will help: http://www.codeproject.com/KB/WPF/WPF_Glimps.aspx

The class can be added in C++ CLI in a seperate DLL.



回答6:

I've scrapped my old answer since it was irrelevant. The new on also used OpenCV (since I'm trying to display an OpenCV image) but it can be adapted to any framework.

The core code is where it takes a memory address address, and the number of bytes to read through numrows, numcols, and byte_size and reads those bytes into a buffer. I'm sure you can adapt that portion of the code for your own needs.

#include "stdafx.h"
#include <windows.h>
#include <cv.h>
#include <highgui.h>
#include <iostream>

using namespace std;
using namespace cv;

void imshow_debug(const LPCVOID address, const int numrows, const int numcols, const int type, const int byte_size, const int step, const string windows_title)
{
    // Initialize
    unsigned long PID; 
    SIZE_T read_bytes = 0;

    // Allocate space for the image
    const int bytes_to_read = numrows*numcols*byte_size;
    uchar *image_data = new uchar[bytes_to_read];
    Mat Image(numrows,numcols,type,image_data,step);

    // Get the handle and PID
    HWND handle = FindWindowA(0, windows_title.c_str());
    if (!FindWindowA(0, windows_title.c_str())) 
    { 
        printf("Window %s not found!", windows_title); 
        exit(0); 
    }
    GetWindowThreadProcessId(handle, &PID);  /* Get windows PID from a window handle */
    HANDLE WindowsProcessHandle = OpenProcess(PROCESS_ALL_ACCESS, false, PID);

    // Read the image
    ReadProcessMemory(WindowsProcessHandle,address,image_data,bytes_to_read,&read_bytes);   
    if(bytes_to_read != read_bytes) 
    {
        cout<<"Could not read entire image"<<endl; 
        exit(0);
    }

    // Display the image
    namedWindow("Image");
    imshow("Image",Image);
    waitKey();

    // Clean up
    CloseHandle(WindowsProcessHandle);
    delete[]image_data;
}

int main(int argc, char* argv[])
{
    imshow_debug((LPVOID)0x03af0370,300,300,CV_64F,sizeof(double),2400,"C:\\Documents and Settings\\jacobm\\My Documents\\Visual Studio 2005\\Projects\\Head\\debug\\SSR_VideoComp.exe");
    return 0;
}