mirror of
https://github.com/wang-bin/QtAV.git
synced 2026-10-28 19:16:48 +08:00
region of interest support. gl and xv not ready
TODO: aspect ratio change if roi changes. setContentRect?
This commit is contained in:
@@ -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
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user