How to save image which is specific area that I clicked of picture Control?

280 Views Asked by At

Hello I'm studying MFC and I wanna know how to save a specific part of image which is in Picture Control when I click.

Here is the sequence what I want to do

I already make a function that when I click grab button, it shows the image in picture control.

After that, I want to save image when I click specific area.

I attach the image to help understand. picture control

"I want to know how to save the surrounding area as an image when I click a specific part of the picture control as shown above."

It would be easy problem, but I'd appreciate it if you understand because it's my first time doing this.

I tryed to use ScreenToClient function, but I failed.

1

There are 1 best solutions below

0
Jerry Coffin On BEST ANSWER

There are quite a few ways to do this, but the general idea is usually pretty much the same:

  1. Get a DC to the screen or the window's client area (aka DC1).
  2. Create a DC compatible with DC1 (aka DC2).
  3. create a CBitmap compatible with DC1, of the size you want to copy/save.
  4. select the bitmap into DC2.
  5. bitblt the area you care about from DC1 to DC2.
  6. Create a CImage object.
  7. Detach the bitmap from the CBitmap, and attach it to the CImage.
  8. Use CImage::Save to save the bitmap to a file.

There are variations (e.g., writing the data to a file without using a CImage), but they tend to be tedious, and unless you're willing to put quite a bit of effort into things, fairly limited as well. e.g., writing a .BMP file on your own isn't terribly difficult, but is a bit tedious.If you want to support writing JPEG, TIFF, PNG, etc., you either need to integrate a number of libraries, or else write quite a bit of code for the file formats. CImage is somewhat limited as well, but at least supports a half dozen or so of the most common formats (and most people find just JPEG, PNG and possibly GIF sufficient).

Here's a bit of tested sample code for saving a 200x200 chunk of whatever's displayed in the current view window into a file named capture.jpg:

void CPicCapView::OnLButtonDown(UINT nFlags, CPoint point) {

    // width and height of area to capture
    static const uint32_t width = 200;
    static const uint32_t height = 200;

    CClientDC dc(this);

    CDC temp;
    temp.CreateCompatibleDC(&dc);

    CBitmap bmp;
    bmp.CreateCompatibleBitmap(&dc, width, height);
    temp.SelectObject(&bmp);

    // x-width/2, y-width/2 to get area centered at click point
    temp.BitBlt(0, 0, width, height, &dc, point.x- width/2, point.y-height/2, SRCCOPY);

    CImage dest;
    dest.Attach((HBITMAP)bmp.Detach());

    // for the moment, just saving to a fixed file name
    dest.Save(L".\\capture.jpg");

    CView::OnLButtonDown(nFlags, point);
}

It might initially seem like you should be able to create the CImage object, use its Create to create a bitmap, and then blit directly from the screen bitmap to the CImage bitmap. Unfortunately, CImage's BitBlt uses the CImage as a source, not a destination, so although there may be some way to get this to work, the obvious method doesn't.