region of interest support. gl and xv not ready

TODO:
aspect ratio change if roi changes. setContentRect?
This commit is contained in:
wang-bin
2013-10-14 00:48:35 +08:00
parent d2c9ebe959
commit 09f37fa31e
7 changed files with 76 additions and 13 deletions
+8 -1
View File
@@ -103,12 +103,19 @@ void Direct2DRenderer::drawFrame()
(FLOAT)d.out_rect.right(),
(FLOAT)d.out_rect.bottom()
};
QRect roi = realROI();
D2D1_RECT_F roi_d2d = {
(FLOAT)roi.left(),
(FLOAT)roi.top(),
(FLOAT)roi.right(),
(FLOAT)roi.bottom()
};
//d.render_target->SetTransform
d.render_target->DrawBitmap(d.bitmap
, &out_rect
, 1 //opacity
, d.interpolation
, NULL);//&D2D1::RectF(0, 0, d.src_width, d.src_height));
, &roi_d2d);
}
void Direct2DRenderer::paintEvent(QPaintEvent *)
+6 -5
View File
@@ -100,24 +100,25 @@ void GDIRenderer::drawFrame()
}
HDC hdc = d.device_context;
HBITMAP hbmp_old = (HBITMAP)SelectObject(d.off_dc, d.off_bitmap);
QRect roi = realROI();
// && image.size() != size()
//assume that the image data is already scaled to out_size(NOT renderer size!)
if (!d.scale_in_renderer || (d.src_width == d.out_rect.width() && d.src_height == d.out_rect.height())) {
/*if (!d.scale_in_renderer || (roi.size() == d.out_rect.size())) {
BitBlt(hdc
, d.out_rect.left(), d.out_rect.top()
, d.out_rect.width(), d.out_rect.height()
, d.off_dc
, 0, 0
, SRCCOPY);
} else {
} else {*/
StretchBlt(hdc
, d.out_rect.left(), d.out_rect.top()
, d.out_rect.width(), d.out_rect.height()
, d.off_dc
, 0, 0
, d.src_width, d.src_height
, roi.x(), roi.y()
, roi.width(), roi.height()
, SRCCOPY);
}
//}
SelectObject(d.off_dc, hbmp_old);
DeleteObject(d.off_bitmap); //avoid mem leak
#endif
+4 -3
View File
@@ -110,11 +110,12 @@ void GraphicsItemRenderer::drawFrame()
d.image = QImage(rendererSize(), QImage::Format_RGB32);
d.image.fill(Qt::black); //maemo 4.7.0: QImage.fill(uint)
}
QRect roi = realROI();
//assume that the image data is already scaled to out_size(NOT renderer size!)
if (!d.scale_in_renderer || d.image.size() == d.out_rect.size()) {
d.painter->drawImage(d.out_rect.topLeft(), d.image);
if (!d.scale_in_renderer || roi.size() == d.out_rect.size()) {
d.painter->drawImage(d.out_rect.topLeft(), d.image, roi);
} else {
d.painter->drawImage(d.out_rect, d.image);
d.painter->drawImage(d.out_rect, d.image, roi);
}
}
+17
View File
@@ -24,6 +24,7 @@
#include <QtCore/QByteArray>
#include <QtCore/QSize>
#include <QtCore/QRectF>
#include <QtAV/AVOutput.h>
/*TODO:
@@ -60,6 +61,7 @@ class Q_EXPORT VideoRenderer : public AVOutput
DPTR_DECLARE_PRIVATE(VideoRenderer)
public:
//TODO: original video size mode
// fillmode: keepsize
enum OutAspectRatioMode {
RendererAspectRatio //Use renderer's aspect ratio, i.e. stretch to fit the renderer rect
, VideoAspectRatio //Use video's aspect ratio and align center in renderer.
@@ -104,6 +106,21 @@ public:
int frameHeight() const;
//The video frame rect in renderer you shoud paint to. e.g. in RendererAspectRatio mode, the rect equals to renderer's
QRect videoRect() const;
/*
* region of interest, ROI
* invalid rect means the whole source rect
* null rect is the whole available source rect. e.g. (0, 0, 0, 0) equals whole source rect
* (20, 30, 0, 0) equals (20, 30, sourceWidth - 20, sourceHeight - 30)
* if |x|<=1, |y|<=1, |width|<1, |height|<1 means the ratio of source rect
* call realROI() to get the frame rect actually to be render
* TODO: nagtive width or height means invert direction. is nagtive necessary?
*/
QRectF regionOfInterest() const;
// TODO: reset aspect ratio to roi.width/roi/heghit
void setRegionOfInterest(qreal x, qreal y, qreal width, qreal height);
void setRegionOfInterest(const QRectF& roi);
// compute the real ROI
QRect realROI() const;
QWidget* widget();
QGraphicsItem* graphicsItem();
+1 -1
View File
@@ -106,7 +106,7 @@ public:
VideoRenderer::Quality quality;
//out_rect: the displayed video frame out_rect in the renderer
QRect out_rect; //TODO: out_out_rect
QRectF roi;
/* Stores but not own the ptr if renderer is a subclass of QWidget.
* Some operations are based on QWidget
*/
+36
View File
@@ -218,6 +218,42 @@ QRect VideoRenderer::videoRect() const
return d_func().out_rect;
}
QRectF VideoRenderer::regionOfInterest() const
{
return d_func().roi;
}
void VideoRenderer::setRegionOfInterest(qreal x, qreal y, qreal width, qreal height)
{
DPTR_D(VideoRenderer);
d.roi = QRectF(x, y, width, height);
}
void VideoRenderer::setRegionOfInterest(const QRectF &roi)
{
d_func().roi = roi;
}
QRect VideoRenderer::realROI() const
{
DPTR_D(const VideoRenderer);
if (!d.roi.isValid()) {
return QRect(0, 0, d.src_width, d.src_height);
}
QRect r = d.roi.toRect();
if (qAbs(d.roi.x()) <= 1)
r.setX(d.roi.x()*qreal(frameWidth()));
if (qAbs(d.roi.y()) <= 1)
r.setY(d.roi.y()*qreal(frameHeight()));
// whole size use width or height = 0, i.e. null size
if (qAbs(d.roi.width()) < 1)
r.setWidth(d.roi.width()*qreal(frameWidth()));
if (qAbs(d.roi.height() < 1))
r.setHeight(d.roi.height()*qreal(frameHeight()));
//TODO: insect with source rect?
return r;
}
QWidget* VideoRenderer::widget()
{
return d_func().widget_holder;
+4 -3
View File
@@ -104,14 +104,15 @@ void WidgetRenderer::drawFrame()
d.image = QImage(rendererSize(), QImage::Format_RGB32);
d.image.fill(Qt::black); //maemo 4.7.0: QImage.fill(uint)
}
QRect roi = realROI();
//assume that the image data is already scaled to out_size(NOT renderer size!)
if (!d.scale_in_renderer || d.image.size() == d.out_rect.size()) {
if (!d.scale_in_renderer || roi.size() == d.out_rect.size()) {
//d.preview = d.image;
d.painter->drawImage(d.out_rect.topLeft(), d.image);
d.painter->drawImage(d.out_rect.topLeft(), d.image, roi);
} else {
//qDebug("size not fit. may slow. %dx%d ==> %dx%d"
// , d.image.size().width(), image.size().height(), d.renderer_width, d.renderer_height);
d.painter->drawImage(d.out_rect, d.image);
d.painter->drawImage(d.out_rect, d.image, roi);
//what's the difference?
//d.painter->drawImage(QPoint(), image.scaled(d.renderer_width, d.renderer_height));
}