Exemple #1
0
void VideoPreviewer::paintEvent(QPaintEvent* event) {
	Q_UNUSED(event);
	QPainter painter(this);

	// Copy the image so the lock isn't held while actually drawing the image.
	// This is fast because QImage is reference counted.
	QImage img;
	QSize source_size;
	{
		SharedLock lock(&m_shared_data);
		img = lock->m_image;
		source_size = lock->m_source_size;
	}

	if(!img.isNull()) {

		// draw the image
		// Scaling is only used if the widget was resized after the image was captured, which is unlikely
		// except when the video is paused. That's good because the quality after Qt's scaling is horrible.
		QSize out_size = CalculateScaledSize(source_size, QSize(width() - 2, height() - 2));
		QPoint out_pos((width() - out_size.width()) / 2, (height() - out_size.height()) / 2);
		QRect out_rect(out_pos, out_size);
		painter.drawImage(out_rect, img);

		// draw the border
		painter.setPen(Qt::black);
		painter.setBrush(Qt::NoBrush);
		painter.drawRect(out_rect.adjusted(-1, -1, 0, 0));

	}

}
Exemple #2
0
void VideoPreviewer::paintEvent(QPaintEvent* event) {
	Q_UNUSED(event);
	QPainter painter(this);

	// copy the image data so the lock isn't held while actually drawing the image
	std::shared_ptr<TempBuffer<uint8_t> > image_buffer;
	int image_stride;
	QSize image_size, source_size;
	{
		SharedLock lock(&m_shared_data);
		image_buffer = lock->m_image_buffer; // shared pointer copy is cheap
		image_stride = lock->m_image_stride;
		image_size = lock->m_image_size;
		source_size = lock->m_source_size;
	}

	if(image_buffer != NULL) {

		// create image (data is not copied)
		QImage img(image_buffer->GetData(), image_size.width(), image_size.height(), image_stride, QImage::Format_RGB32);

		// draw the image
		// Scaling is only used if the widget was resized after the image was captured, which is unlikely
		// except when the video is paused. That's good because the quality after Qt's scaling is horrible.
		QSize out_size = CalculateScaledSize(source_size, QSize(width() - 2, height() - 2));
		QPoint out_pos((width() - out_size.width()) / 2, (height() - out_size.height()) / 2);
		QRect out_rect(out_pos, out_size);
		painter.drawImage(out_rect, img);

		// draw the border
		painter.setPen(Qt::black);
		painter.setBrush(Qt::NoBrush);
		painter.drawRect(out_rect.adjusted(-1, -1, 0, 0));

	}

}
Exemple #3
0
void MergeRects(const CAtlList<CRect>& input, CAtlList<CRect>* output)
{
    if(output==NULL || input.GetCount()==0)
        return;

    struct Segment
    {
        int top, bottom;
        int seg_start, seg_end;
        CAtlList<CRect>* rects;

        Segment()
        {
            rects = NULL;
        }
        ~Segment()
        {
            delete rects;
        }
    };

    struct BreakPoint
    {
        int x;
        const RECT* rect;

        inline bool operator<(const BreakPoint& breakpoint ) const
        {
            return (x < breakpoint.x);
        }
    };

    int input_count = input.GetCount();
    std::vector<int> vertical_breakpoints(2*input_count);
    std::vector<BreakPoint> herizon_breakpoints(input_count + 1);

    POSITION pos = input.GetHeadPosition();
    for(int i=0; i<input_count; i++)
    {
        const CRect& rect = input.GetNext(pos);
        vertical_breakpoints[2*i]=rect.top;
        vertical_breakpoints[2*i+1]=rect.bottom;

        herizon_breakpoints[i].x = rect.left;
        herizon_breakpoints[i].rect = &rect;
    }
    CRect sentinel_rect(INT_MAX, 0, INT_MAX, INT_MAX);
    herizon_breakpoints[input_count].x = INT_MAX;//sentinel
    herizon_breakpoints[input_count].rect = &sentinel_rect;

    std::sort(vertical_breakpoints.begin(), vertical_breakpoints.end());
    std::sort(herizon_breakpoints.begin(), herizon_breakpoints.end());

    std::vector<Segment> tempSegments(vertical_breakpoints.size()-1);
    int ptr = 1, prev = vertical_breakpoints[0], count = 0;
    for(int i = vertical_breakpoints.size()-1; i > 0; i--, ptr++)
    {
        if(vertical_breakpoints[ptr] != prev)
        {
            Segment& seg = tempSegments[count];
            seg.top = prev;
            seg.bottom = vertical_breakpoints[ptr];
            seg.seg_end = seg.seg_start = INT_MIN;//important! cannot use =0
            seg.rects = new CAtlList<CRect>();

            prev = vertical_breakpoints[ptr];
            count++;
        }
    }    

    for(int i=0; i<=input_count; i++)
    {
        const CRect& rect = *herizon_breakpoints[i].rect;

        int start = 0, mid, end = count;

        while(start<end)
        {
            mid = (start+end)>>1;
            if(tempSegments[mid].top < rect.top)
            {
                start = mid+1;
            }
            else
            {
                end = mid;
            }
        }
        for(; start < count && tempSegments[start].bottom <= rect.bottom; start++)
        {
            if(tempSegments[start].seg_end<rect.left)
            {
                CRect out_rect( tempSegments[start].seg_start, tempSegments[start].top, tempSegments[start].seg_end, tempSegments[start].bottom );
                tempSegments[start].rects->AddTail( out_rect );
                tempSegments[start].seg_start = rect.left;
                tempSegments[start].seg_end = rect.right;
            }
            else if( tempSegments[start].seg_end<rect.right )
            {
                tempSegments[start].seg_end=rect.right;
            }
        }
    }
    for (int i=count-1;i>0;i--)
    {
        CAtlList<CRect>& cur_line = *tempSegments[i].rects;
        CRect cur_rect = cur_line.RemoveTail();
        if(tempSegments[i].top == tempSegments[i-1].bottom)
        {            
            CAtlList<CRect>& upper_line = *tempSegments[i-1].rects;

            POSITION pos = upper_line.GetTailPosition();                          
            while(pos)
            {
                CRect& upper_rect = upper_line.GetPrev(pos);
                while( upper_rect.right<cur_rect.right || upper_rect.left<cur_rect.left )
                {
                    output->AddHead(cur_rect);
                    //if(!cur_line.IsEmpty())
                    cur_rect = cur_line.RemoveTail();
                }
                if(cur_line.IsEmpty())
                    break;

                if(upper_rect.right==cur_rect.right && upper_rect.left==cur_rect.left)
                {
                    upper_rect.bottom = cur_rect.bottom;
                    //if(!cur_line.IsEmpty())
                    cur_rect = cur_line.RemoveTail();
                }
                //else if ( upper_rect.right>cur_rect.right || upper_rect.left>cur_rect.left )             
            }
        }                
        while(!cur_line.IsEmpty())
        {
            output->AddHead(cur_rect);
            cur_rect = cur_line.RemoveTail();
        }
    }
    if(count>0)
    {
        CAtlList<CRect>& cur_line = *tempSegments[0].rects;
        CRect cur_rect = cur_line.RemoveTail();
        while(!cur_line.IsEmpty())
        {
            output->AddHead(cur_rect);
            cur_rect = cur_line.RemoveTail();
        }
    }
}