Python在OpenCV中放大后捕获图像的特定部分

发布于 2025-01-12 15:53:50 字数 10115 浏览 4 评论 0原文

因此,我尝试使用网络摄像头进行放大和缩小,并在缩放后捕获实时网络摄像头中特定部分的图像。但是,我可以放大和缩小,但通过使用“cam.read()”,我只能捕获整个图像,而不能捕获已缩放的图像的特定部分。我已经定义了 ROI,但问题是现在 ROI 正在工作,但我无法放大或缩小图像。我似乎找不到问题所在。

import cv2
import time
import os
import datetime
from threading import Thread
from queue import Queue
import numpy as np
import imutils
from PIL import Image


class Camera:
    def __init__(self, mirror=False):
        self.data = None
        self.cam = cv2.VideoCapture(0,  cv2.CAP_DSHOW)

        self.WIDTH = 640
        self.HEIGHT = 480

        self.center_x = self.WIDTH / 2
        self.center_y = self.HEIGHT / 2
        self.touched_zoom = False

        self.image_queue = Queue()
        self.video_queue = Queue()

        self.scale = 1
        self.__setup()

        self.recording = False
        self.image_coordinates = []
        self.extract = False
        self.selected_ROI = False

        self.select_roi()

        self.mirror = mirror

    def __setup(self):
        self.cam.set(cv2.CAP_PROP_FRAME_WIDTH, self.WIDTH)
        self.cam.set(cv2.CAP_PROP_FRAME_HEIGHT, self.HEIGHT)
        time.sleep(2)

    def get_location(self, x, y):
        self.center_x = x
        self.center_y = y
        self.touched_zoom = True

    def stream(self):

        def streaming():

            self.ret = True
            while self.ret:
                self.ret, np_image = self.cam.read()
                if np_image is None:
                    continue
                if self.mirror:

                    np_image = cv2.flip(np_image, 1)
                if self.touched_zoom:
                    np_image = self.__zoom(np_image, (self.center_x, self.center_y))
                else:
                    if not self.scale == 1:
                        np_image = self.__zoom(np_image)
                self.data = np_image
                k = cv2.waitKey(1)
                if k == ord('q'):
                    self.release()
                    break

        Thread(target=streaming).start()

    def __zoom(self, img, center=None):

        height, width = img.shape[:2]
        if center is None:

            center_x = int(width / 2)
            center_y = int(height / 2)
            radius_x, radius_y = int(width / 2), int(height / 2)
        else:

            rate = height / width
            center_x, center_y = center


            if center_x < width * (1-rate):
                center_x = width * (1-rate)
            elif center_x > width * rate:
                center_x = width * rate
            if center_y < height * (1-rate):
                center_y = height * (1-rate)
            elif center_y > height * rate:
                center_y = height * rate

            center_x, center_y = int(center_x), int(center_y)
            left_x, right_x = center_x, int(width - center_x)
            up_y, down_y = int(height - center_y), center_y
            radius_x = min(left_x, right_x)
            radius_y = min(up_y, down_y)


        radius_x, radius_y = int(self.scale * radius_x), int(self.scale * radius_y)


        min_x, max_x = center_x - radius_x, center_x + radius_x
        min_y, max_y = center_y - radius_y, center_y + radius_y


        cropped = img[min_y:max_y, min_x:max_x]

        new_cropped = cv2.resize(cropped, (width, height), interpolation=cv2.INTER_CUBIC)

        return new_cropped

    def touch_init(self):
        self.center_x = self.WIDTH / 2
        self.center_y = self.HEIGHT / 2
        self.touched_zoom = False
        self.scale = 1

    def zoom_out(self):

        if self.scale < 1:
            self.scale += 0.1
        if self.scale == 1:
            self.center_x = self.WIDTH
            self.center_y = self.HEIGHT
            self.touched_zoom = False

    def zoom_in(self):

        if self.scale > 0.2:
            self.scale -= 0.1

    def zoom(self, num):
        if num == 0:
            self.zoom_in()
        elif num == 1:
            self.zoom_out()
        elif num == 2:
            self.touch_init()


    def save_picture(self):


        ret, img = self.cam.read()
        if ret:
            now1 = datetime.datetime.now()
            now_str1 = now1.strftime("%Y-%m-%d-%H-%M-%S")
            outfilename1 = 'Img-{}.jpg'.format(now_str1)
            path = 'C:/Users/dashi/Documents/MyRiV/espeyh_images'
            cv2.imwrite(os.path.join(path, outfilename1), img)
            path1 = ('C:/Users/dashi/Documents/MyRiV/espeyh_images/' + outfilename1)

            imag = cv2.imread(path1)
            lower = np.array([140, 140, 140])
            upper = np.array([255, 255, 255])
            thresh = cv2.inRange(imag, lower, upper)
            kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (26, 30))
            morph = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)
            mask = 255 - morph
            result = cv2.bitwise_and(imag, imag, mask=mask)
            cv2.imshow('Background Removed', result)
            outfilename2 = 'Img-{}.jpg'.format(now_str1)
            path2 = ('C:/Users/dashi/Documents/MyRiV/modified_images')
            cv2.imwrite(os.path.join(path2, outfilename2), result)


    def record_video(self):

        fc = 20.0
        record_start_time = time.time()
        now = datetime.datetime.now()
        date = now.strftime('%Y%m%d')
        t = now.strftime('%H')
        num = 1
        filename = 'C:/Users/dashi/Documents/MyRiV/espeyh_videos/captured_{}_{}.avi'.format(date, t, num)
        while os.path.exists(filename):
            num += 1
            filename = 'videos/captured_{}_{}_{}.avi'.format(date, t, num)
        codec = cv2.VideoWriter_fourcc('D', 'I', 'V', 'X')
        out = cv2.VideoWriter(filename, codec, fc, (int(self.cam.get(3)), int(self.cam.get(4))))
        while self.recording:
            if time.time() - record_start_time >= 600:
                self.record_video()
                break
            ret, frame = self.cam.read()
            if ret:
                if len(os.listdir('C:/Users/dashi/Documents/MyRiV/espeyh_videos')) >= 100:
                    name = self.video_queue.get()
                    if os.path.exists(name):
                        os.remove(name)
                out.write(frame)
                self.video_queue.put_nowait(filename)
            k = cv2.waitKey(1)
            if k == ord('q'):
                break

    def crop_ROI(self):
        if self.selected_ROI:
            self.cropped_image = self.frame.copy()

            x1 = self.image_coordinates[0][0]
            y1 = self.image_coordinates[0][1]
            x2 = self.image_coordinates[1][0]
            y2 = self.image_coordinates[1][1]

            self.cropped_image = self.cropped_image[y1:y2, x1:x2]

            print('Cropped image: {} {}'.format(self.image_coordinates[0], self.image_coordinates[1]))
        else:
            print('Select ROI to crop before cropping')

    def show_cropped_ROI(self):
        cv2.imshow('cropped image', self.cropped_image)

    def select_roi(self):
        while True:
            if self.cam.isOpened():
                # Read frame
                (self.status, self.frame) = self.cam.read()
                cv2.imshow('image', self.frame)
                key = cv2.waitKey(2)

                # Crop image
                if key == ord('c'):
                    self.clone = self.frame.copy()
                    cv2.namedWindow('image')
                    cv2.setMouseCallback('image', self.mouse_callback)
                    while True:
                        key = cv2.waitKey(2)
                        cv2.imshow('image', self.clone)

                        # Crop and display cropped image
                        if key == ord('c'):
                            self.crop_ROI()
                            self.show_cropped_ROI()

                        # Resume video
                        if key == ord('r'):
                            break
                # Close program with keyboard 'q'
                if key == ord('q'):
                    cv2.destroyAllWindows()
                    exit(1)
            else:
                pass

    def show(self):
        while True:
            frame = self.data
            if frame is not None:
                cv2.imshow('Zooming', frame)
                cv2.setMouseCallback('Zooming', self.mouse_callback)
            key = cv2.waitKey(1)
            if key == ord('f'):
                if key == ord('q'):
                    self.release()
                    cv2.destroyAllWindows()
                    break

                elif key == ord('z'):

                    self.zoom_in()

                elif key == ord('x'):

                    self.zoom_out()

                elif key == ord('p'):

                    self.save_picture()

                elif key == ord('v'):

                    self.touch_init()

                elif key == ord('r'):

                    self.recording = not self.recording
                    if self.recording:
                        t = Thread(target=cam.record_video)
                        t.start()


            elif key == ord('k'):
                self.select_roi()

    def release(self):
        self.cam.release()
        cv2.destroyAllWindows()

    def mouse_callback(self, event, x, y, flag, parameters):
        if event == cv2.EVENT_LBUTTONDBLCLK:
            self.get_location(x, y)
            self.zoom_in()
        elif event == cv2.EVENT_RBUTTONDOWN:
            self.zoom_out()
        elif event == cv2.EVENT_LBUTTONDOWN:
            self.image_coordinates = [(x,y)]
            self.extract = True
        elif event == cv2.EVENT_LBUTTONUP:
            self.image_coordinates.append((x,y))
            self.extract = False

            self.selected_ROI = True

            # Draw rectangle around ROI
            cv2.rectangle(self.clone, self.image_coordinates[0], self.image_coordinates[1], (0,255,0), 2)
        elif event == cv2.EVENT_RBUTTONDOWN:
            self.clone = self.frame.copy()
            self.selected_ROI = False



if __name__ == '__main__':
    cam = Camera(mirror=True)
    cam.stream()
    cam.show()

So I'm trying to zoom in and out using my webcam and capture the image of a specific part in the live webcam after zooming. However, I'm able to zoom in and out but by using "cam.read()" I am only able to capture the entire image and not the specific part of the image that I have zoomed. I have defined the ROI but the issue is now that the ROI is working but i can't get the image to zoom in or out. I can't seem to find the problem.

import cv2
import time
import os
import datetime
from threading import Thread
from queue import Queue
import numpy as np
import imutils
from PIL import Image


class Camera:
    def __init__(self, mirror=False):
        self.data = None
        self.cam = cv2.VideoCapture(0,  cv2.CAP_DSHOW)

        self.WIDTH = 640
        self.HEIGHT = 480

        self.center_x = self.WIDTH / 2
        self.center_y = self.HEIGHT / 2
        self.touched_zoom = False

        self.image_queue = Queue()
        self.video_queue = Queue()

        self.scale = 1
        self.__setup()

        self.recording = False
        self.image_coordinates = []
        self.extract = False
        self.selected_ROI = False

        self.select_roi()

        self.mirror = mirror

    def __setup(self):
        self.cam.set(cv2.CAP_PROP_FRAME_WIDTH, self.WIDTH)
        self.cam.set(cv2.CAP_PROP_FRAME_HEIGHT, self.HEIGHT)
        time.sleep(2)

    def get_location(self, x, y):
        self.center_x = x
        self.center_y = y
        self.touched_zoom = True

    def stream(self):

        def streaming():

            self.ret = True
            while self.ret:
                self.ret, np_image = self.cam.read()
                if np_image is None:
                    continue
                if self.mirror:

                    np_image = cv2.flip(np_image, 1)
                if self.touched_zoom:
                    np_image = self.__zoom(np_image, (self.center_x, self.center_y))
                else:
                    if not self.scale == 1:
                        np_image = self.__zoom(np_image)
                self.data = np_image
                k = cv2.waitKey(1)
                if k == ord('q'):
                    self.release()
                    break

        Thread(target=streaming).start()

    def __zoom(self, img, center=None):

        height, width = img.shape[:2]
        if center is None:

            center_x = int(width / 2)
            center_y = int(height / 2)
            radius_x, radius_y = int(width / 2), int(height / 2)
        else:

            rate = height / width
            center_x, center_y = center


            if center_x < width * (1-rate):
                center_x = width * (1-rate)
            elif center_x > width * rate:
                center_x = width * rate
            if center_y < height * (1-rate):
                center_y = height * (1-rate)
            elif center_y > height * rate:
                center_y = height * rate

            center_x, center_y = int(center_x), int(center_y)
            left_x, right_x = center_x, int(width - center_x)
            up_y, down_y = int(height - center_y), center_y
            radius_x = min(left_x, right_x)
            radius_y = min(up_y, down_y)


        radius_x, radius_y = int(self.scale * radius_x), int(self.scale * radius_y)


        min_x, max_x = center_x - radius_x, center_x + radius_x
        min_y, max_y = center_y - radius_y, center_y + radius_y


        cropped = img[min_y:max_y, min_x:max_x]

        new_cropped = cv2.resize(cropped, (width, height), interpolation=cv2.INTER_CUBIC)

        return new_cropped

    def touch_init(self):
        self.center_x = self.WIDTH / 2
        self.center_y = self.HEIGHT / 2
        self.touched_zoom = False
        self.scale = 1

    def zoom_out(self):

        if self.scale < 1:
            self.scale += 0.1
        if self.scale == 1:
            self.center_x = self.WIDTH
            self.center_y = self.HEIGHT
            self.touched_zoom = False

    def zoom_in(self):

        if self.scale > 0.2:
            self.scale -= 0.1

    def zoom(self, num):
        if num == 0:
            self.zoom_in()
        elif num == 1:
            self.zoom_out()
        elif num == 2:
            self.touch_init()


    def save_picture(self):


        ret, img = self.cam.read()
        if ret:
            now1 = datetime.datetime.now()
            now_str1 = now1.strftime("%Y-%m-%d-%H-%M-%S")
            outfilename1 = 'Img-{}.jpg'.format(now_str1)
            path = 'C:/Users/dashi/Documents/MyRiV/espeyh_images'
            cv2.imwrite(os.path.join(path, outfilename1), img)
            path1 = ('C:/Users/dashi/Documents/MyRiV/espeyh_images/' + outfilename1)

            imag = cv2.imread(path1)
            lower = np.array([140, 140, 140])
            upper = np.array([255, 255, 255])
            thresh = cv2.inRange(imag, lower, upper)
            kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (26, 30))
            morph = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)
            mask = 255 - morph
            result = cv2.bitwise_and(imag, imag, mask=mask)
            cv2.imshow('Background Removed', result)
            outfilename2 = 'Img-{}.jpg'.format(now_str1)
            path2 = ('C:/Users/dashi/Documents/MyRiV/modified_images')
            cv2.imwrite(os.path.join(path2, outfilename2), result)


    def record_video(self):

        fc = 20.0
        record_start_time = time.time()
        now = datetime.datetime.now()
        date = now.strftime('%Y%m%d')
        t = now.strftime('%H')
        num = 1
        filename = 'C:/Users/dashi/Documents/MyRiV/espeyh_videos/captured_{}_{}.avi'.format(date, t, num)
        while os.path.exists(filename):
            num += 1
            filename = 'videos/captured_{}_{}_{}.avi'.format(date, t, num)
        codec = cv2.VideoWriter_fourcc('D', 'I', 'V', 'X')
        out = cv2.VideoWriter(filename, codec, fc, (int(self.cam.get(3)), int(self.cam.get(4))))
        while self.recording:
            if time.time() - record_start_time >= 600:
                self.record_video()
                break
            ret, frame = self.cam.read()
            if ret:
                if len(os.listdir('C:/Users/dashi/Documents/MyRiV/espeyh_videos')) >= 100:
                    name = self.video_queue.get()
                    if os.path.exists(name):
                        os.remove(name)
                out.write(frame)
                self.video_queue.put_nowait(filename)
            k = cv2.waitKey(1)
            if k == ord('q'):
                break

    def crop_ROI(self):
        if self.selected_ROI:
            self.cropped_image = self.frame.copy()

            x1 = self.image_coordinates[0][0]
            y1 = self.image_coordinates[0][1]
            x2 = self.image_coordinates[1][0]
            y2 = self.image_coordinates[1][1]

            self.cropped_image = self.cropped_image[y1:y2, x1:x2]

            print('Cropped image: {} {}'.format(self.image_coordinates[0], self.image_coordinates[1]))
        else:
            print('Select ROI to crop before cropping')

    def show_cropped_ROI(self):
        cv2.imshow('cropped image', self.cropped_image)

    def select_roi(self):
        while True:
            if self.cam.isOpened():
                # Read frame
                (self.status, self.frame) = self.cam.read()
                cv2.imshow('image', self.frame)
                key = cv2.waitKey(2)

                # Crop image
                if key == ord('c'):
                    self.clone = self.frame.copy()
                    cv2.namedWindow('image')
                    cv2.setMouseCallback('image', self.mouse_callback)
                    while True:
                        key = cv2.waitKey(2)
                        cv2.imshow('image', self.clone)

                        # Crop and display cropped image
                        if key == ord('c'):
                            self.crop_ROI()
                            self.show_cropped_ROI()

                        # Resume video
                        if key == ord('r'):
                            break
                # Close program with keyboard 'q'
                if key == ord('q'):
                    cv2.destroyAllWindows()
                    exit(1)
            else:
                pass

    def show(self):
        while True:
            frame = self.data
            if frame is not None:
                cv2.imshow('Zooming', frame)
                cv2.setMouseCallback('Zooming', self.mouse_callback)
            key = cv2.waitKey(1)
            if key == ord('f'):
                if key == ord('q'):
                    self.release()
                    cv2.destroyAllWindows()
                    break

                elif key == ord('z'):

                    self.zoom_in()

                elif key == ord('x'):

                    self.zoom_out()

                elif key == ord('p'):

                    self.save_picture()

                elif key == ord('v'):

                    self.touch_init()

                elif key == ord('r'):

                    self.recording = not self.recording
                    if self.recording:
                        t = Thread(target=cam.record_video)
                        t.start()


            elif key == ord('k'):
                self.select_roi()

    def release(self):
        self.cam.release()
        cv2.destroyAllWindows()

    def mouse_callback(self, event, x, y, flag, parameters):
        if event == cv2.EVENT_LBUTTONDBLCLK:
            self.get_location(x, y)
            self.zoom_in()
        elif event == cv2.EVENT_RBUTTONDOWN:
            self.zoom_out()
        elif event == cv2.EVENT_LBUTTONDOWN:
            self.image_coordinates = [(x,y)]
            self.extract = True
        elif event == cv2.EVENT_LBUTTONUP:
            self.image_coordinates.append((x,y))
            self.extract = False

            self.selected_ROI = True

            # Draw rectangle around ROI
            cv2.rectangle(self.clone, self.image_coordinates[0], self.image_coordinates[1], (0,255,0), 2)
        elif event == cv2.EVENT_RBUTTONDOWN:
            self.clone = self.frame.copy()
            self.selected_ROI = False



if __name__ == '__main__':
    cam = Camera(mirror=True)
    cam.stream()
    cam.show()

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

沒落の蓅哖 2025-01-19 15:53:50

您应该按照与显示图像相同的方式裁剪正在录制的图像。

另外,您正在从 2 个线程读取 VideoCapture。我认为这不是一个好主意:您可能正在显示和记录超过 2 个图像。(显示第一个图像,记录第二个图像,显示第三个图像,...)。

您应该仅在一处调用 self.cam.read(),根据需要裁剪图像,并使其可用于显示和录制。

You should crop the images you are recording the same way you did for the display.

Also, you are reading from the VideoCapture from 2 threads. I don't think that's a good idea : you are probably displaying and recording one image over 2. (the first is displayed, the second is recorded, the third is displayed, ...).

You should call self.cam.read() at one place only, crop the image if needed, and make it available for both display and recording.

枕梦 2025-01-19 15:53:50

基本思想是决定鼠标滚轮每次改变的比例。获得当前比例(相对于原始图像)和要在屏幕上显示的正确图像区域后,您可以获得缩放图像上矩形的位置和长度。所以你可以在缩放图像上绘制这个矩形。

在我的 github 中,检查 Fastest_Image_Pattern_Matching/ELCVMatchTool/ELCVMatchToolDlg.cpp 中的 OnMouseWheel () 和 RefreshSrcView () 可能会给出你想要什么。

虽然是c++代码,但只使用了imshow()和resize(),这意味着转换为python代码对你来说很容易。
专注于如何更改比例以及如何在缩放图像中绘制新矩形就足够了。

影响:
输入图片此处描述
输入图片这里的描述

部分代码:

BOOL CELCVMatchToolDlg::OnMouseWheel (UINT nFlags, short zDelta, CPoint pt)
{
    POINT pointCursor;
    GetCursorPos (&pointCursor);
    ScreenToClient (&pointCursor);
    // TODO: 在此加入您的訊息處理常式程式碼和 (或) 呼叫預設值
    if (zDelta > 0)
    {
        if (m_iScaleTimes == MAX_SCALE_TIMES)
            return TRUE;
        else
            m_iScaleTimes++;
    }
    if (zDelta < 0)
    {
        if (m_iScaleTimes == MIN_SCALE_TIMES)
            return TRUE;
        else
            m_iScaleTimes--;
    }
    CRect rect;
    //GetWindowRect (rect);
    GetDlgItem (IDC_STATIC_SRC_VIEW)->GetWindowRect (rect);//重要

    if (m_iScaleTimes == 0)
        g_dCompensationX = g_dCompensationY = 0;

    int iMouseOffsetX = pt.x - (rect.left + 1);
    int iMouseOffsetY = pt.y - (rect.top + 1);

    double dPixelX = (m_hScrollBar.GetScrollPos () + iMouseOffsetX + g_dCompensationX) / m_dNewScale;
    double dPixelY = (m_vScrollBar.GetScrollPos () + iMouseOffsetY + g_dCompensationY) / m_dNewScale;


    m_dNewScale = m_dSrcScale * pow (SCALE_RATIO, m_iScaleTimes);

    if (m_iScaleTimes != 0)
    {
        int iWidth = m_matSrc.cols;
        int iHeight = m_matSrc.rows;

        
        m_hScrollBar.SetScrollRange (0, int (m_dNewScale * iWidth - m_dSrcScale * iWidth) - 1 + BAR_SIZE);
        m_vScrollBar.SetScrollRange (0, int (m_dNewScale * iHeight - m_dSrcScale * iHeight) - 1 + BAR_SIZE);
        int iBarPosX = int (dPixelX * m_dNewScale - iMouseOffsetX + 0.5);
        m_hScrollBar.SetScrollPos (iBarPosX);
        m_hScrollBar.ShowWindow (SW_SHOW);
        g_dCompensationX = -iBarPosX + (dPixelX * m_dNewScale - iMouseOffsetX);

        int iBarPosY = int (dPixelY * m_dNewScale - iMouseOffsetY + 0.5);
        m_vScrollBar.SetScrollPos (iBarPosY);
        m_vScrollBar.ShowWindow (SW_SHOW);
        g_dCompensationY = -iBarPosY + (dPixelY * m_dNewScale - iMouseOffsetY);

        //滑塊大小
        SCROLLINFO infoH;
        infoH.cbSize = sizeof (SCROLLINFO);
        infoH.fMask = SIF_PAGE;
        infoH.nPage = BAR_SIZE;
        m_hScrollBar.SetScrollInfo (&infoH);

        SCROLLINFO infoV;
        infoV.cbSize = sizeof (SCROLLINFO);
        infoV.fMask = SIF_PAGE;
        infoV.nPage = BAR_SIZE;
        m_vScrollBar.SetScrollInfo (&infoV);
        //滑塊大小

    }
    else
    {
        m_hScrollBar.SetScrollPos (0);
        m_hScrollBar.ShowWindow (SW_HIDE);
        m_vScrollBar.SetScrollPos (0);
        m_vScrollBar.ShowWindow (SW_HIDE);
    }
    RefreshSrcView ();
    return CDialogEx::OnMouseWheel (nFlags, zDelta, pt);
}

The basic idea is deciding the scale changed every time on mouse wheel. After you get the current scale (v.s. origin image) and correct region of image you want to show on screen, you can get the position and length of rectangle on scaled image. So you can draw this rectangle on scaled image.

In my github,checking OnMouseWheel () and RefreshSrcView () in Fastest_Image_Pattern_Matching/ELCVMatchTool/ELCVMatchToolDlg.cpp may give what you want.

Although it's c++ code, only imshow () and resize () are used, meaning that transforming to python code is easy for you.
Focusing on how I change the scale and how the new rectangle to be draw in scaled image will be enough.

Effect:
enter image description here
enter image description here

Part of the code:

BOOL CELCVMatchToolDlg::OnMouseWheel (UINT nFlags, short zDelta, CPoint pt)
{
    POINT pointCursor;
    GetCursorPos (&pointCursor);
    ScreenToClient (&pointCursor);
    // TODO: 在此加入您的訊息處理常式程式碼和 (或) 呼叫預設值
    if (zDelta > 0)
    {
        if (m_iScaleTimes == MAX_SCALE_TIMES)
            return TRUE;
        else
            m_iScaleTimes++;
    }
    if (zDelta < 0)
    {
        if (m_iScaleTimes == MIN_SCALE_TIMES)
            return TRUE;
        else
            m_iScaleTimes--;
    }
    CRect rect;
    //GetWindowRect (rect);
    GetDlgItem (IDC_STATIC_SRC_VIEW)->GetWindowRect (rect);//重要

    if (m_iScaleTimes == 0)
        g_dCompensationX = g_dCompensationY = 0;

    int iMouseOffsetX = pt.x - (rect.left + 1);
    int iMouseOffsetY = pt.y - (rect.top + 1);

    double dPixelX = (m_hScrollBar.GetScrollPos () + iMouseOffsetX + g_dCompensationX) / m_dNewScale;
    double dPixelY = (m_vScrollBar.GetScrollPos () + iMouseOffsetY + g_dCompensationY) / m_dNewScale;


    m_dNewScale = m_dSrcScale * pow (SCALE_RATIO, m_iScaleTimes);

    if (m_iScaleTimes != 0)
    {
        int iWidth = m_matSrc.cols;
        int iHeight = m_matSrc.rows;

        
        m_hScrollBar.SetScrollRange (0, int (m_dNewScale * iWidth - m_dSrcScale * iWidth) - 1 + BAR_SIZE);
        m_vScrollBar.SetScrollRange (0, int (m_dNewScale * iHeight - m_dSrcScale * iHeight) - 1 + BAR_SIZE);
        int iBarPosX = int (dPixelX * m_dNewScale - iMouseOffsetX + 0.5);
        m_hScrollBar.SetScrollPos (iBarPosX);
        m_hScrollBar.ShowWindow (SW_SHOW);
        g_dCompensationX = -iBarPosX + (dPixelX * m_dNewScale - iMouseOffsetX);

        int iBarPosY = int (dPixelY * m_dNewScale - iMouseOffsetY + 0.5);
        m_vScrollBar.SetScrollPos (iBarPosY);
        m_vScrollBar.ShowWindow (SW_SHOW);
        g_dCompensationY = -iBarPosY + (dPixelY * m_dNewScale - iMouseOffsetY);

        //滑塊大小
        SCROLLINFO infoH;
        infoH.cbSize = sizeof (SCROLLINFO);
        infoH.fMask = SIF_PAGE;
        infoH.nPage = BAR_SIZE;
        m_hScrollBar.SetScrollInfo (&infoH);

        SCROLLINFO infoV;
        infoV.cbSize = sizeof (SCROLLINFO);
        infoV.fMask = SIF_PAGE;
        infoV.nPage = BAR_SIZE;
        m_vScrollBar.SetScrollInfo (&infoV);
        //滑塊大小

    }
    else
    {
        m_hScrollBar.SetScrollPos (0);
        m_hScrollBar.ShowWindow (SW_HIDE);
        m_vScrollBar.SetScrollPos (0);
        m_vScrollBar.ShowWindow (SW_HIDE);
    }
    RefreshSrcView ();
    return CDialogEx::OnMouseWheel (nFlags, zDelta, pt);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文