mirror of
https://github.com/f4exb/sdrangel.git
synced 2024-09-20 11:56:36 -04:00
ATV Modulator: text overlay for still images
This commit is contained in:
parent
e24c7bcf2c
commit
b42d39108a
@ -31,6 +31,8 @@ MESSAGE_CLASS_DEFINITION(ATVMod::MsgReportVideoFileSourceStreamTiming, Message)
|
|||||||
MESSAGE_CLASS_DEFINITION(ATVMod::MsgReportVideoFileSourceStreamData, Message)
|
MESSAGE_CLASS_DEFINITION(ATVMod::MsgReportVideoFileSourceStreamData, Message)
|
||||||
MESSAGE_CLASS_DEFINITION(ATVMod::MsgConfigureCameraIndex, Message)
|
MESSAGE_CLASS_DEFINITION(ATVMod::MsgConfigureCameraIndex, Message)
|
||||||
MESSAGE_CLASS_DEFINITION(ATVMod::MsgReportCameraData, Message)
|
MESSAGE_CLASS_DEFINITION(ATVMod::MsgReportCameraData, Message)
|
||||||
|
MESSAGE_CLASS_DEFINITION(ATVMod::MsgConfigureOverlayText, Message)
|
||||||
|
MESSAGE_CLASS_DEFINITION(ATVMod::MsgConfigureShowOverlayText, Message)
|
||||||
|
|
||||||
const float ATVMod::m_blackLevel = 0.3f;
|
const float ATVMod::m_blackLevel = 0.3f;
|
||||||
const float ATVMod::m_spanLevel = 0.7f;
|
const float ATVMod::m_spanLevel = 0.7f;
|
||||||
@ -50,7 +52,8 @@ ATVMod::ATVMod() :
|
|||||||
m_videoPrevFPSCount(0),
|
m_videoPrevFPSCount(0),
|
||||||
m_videoEOF(false),
|
m_videoEOF(false),
|
||||||
m_videoOK(false),
|
m_videoOK(false),
|
||||||
m_cameraIndex(-1)
|
m_cameraIndex(-1),
|
||||||
|
m_showOverlayText(false)
|
||||||
{
|
{
|
||||||
setObjectName("ATVMod");
|
setObjectName("ATVMod");
|
||||||
scanCameras();
|
scanCameras();
|
||||||
@ -489,6 +492,34 @@ bool ATVMod::handleMessage(const Message& cmd)
|
|||||||
getOutputMessageQueue()->push(report);
|
getOutputMessageQueue()->push(report);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (MsgConfigureOverlayText::match(cmd))
|
||||||
|
{
|
||||||
|
MsgConfigureOverlayText& cfg = (MsgConfigureOverlayText&) cmd;
|
||||||
|
m_overlayText = cfg.getOverlayText().toStdString();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (MsgConfigureShowOverlayText::match(cmd))
|
||||||
|
{
|
||||||
|
MsgConfigureShowOverlayText& cfg = (MsgConfigureShowOverlayText&) cmd;
|
||||||
|
bool showOverlayText = cfg.getShowOverlayText();
|
||||||
|
|
||||||
|
if (!m_imageFromFile.empty())
|
||||||
|
{
|
||||||
|
m_imageFromFile.copyTo(m_imageOriginal);
|
||||||
|
|
||||||
|
if (showOverlayText) {
|
||||||
|
qDebug("ATVMod::handleMessage: overlay text");
|
||||||
|
mixImageAndText(m_imageOriginal);
|
||||||
|
} else{
|
||||||
|
qDebug("ATVMod::handleMessage: clear text");
|
||||||
|
}
|
||||||
|
|
||||||
|
resizeImage();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_showOverlayText = showOverlayText;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@ -621,11 +652,17 @@ void ATVMod::applyStandard()
|
|||||||
|
|
||||||
void ATVMod::openImage(const QString& fileName)
|
void ATVMod::openImage(const QString& fileName)
|
||||||
{
|
{
|
||||||
m_imageOriginal = cv::imread(qPrintable(fileName), CV_LOAD_IMAGE_GRAYSCALE);
|
m_imageFromFile = cv::imread(qPrintable(fileName), CV_LOAD_IMAGE_GRAYSCALE);
|
||||||
m_imageOK = m_imageOriginal.data != 0;
|
m_imageOK = m_imageFromFile.data != 0;
|
||||||
|
|
||||||
if (m_imageOK)
|
if (m_imageOK)
|
||||||
{
|
{
|
||||||
|
m_imageFromFile.copyTo(m_imageOriginal);
|
||||||
|
|
||||||
|
if (m_showOverlayText) {
|
||||||
|
mixImageAndText(m_imageOriginal);
|
||||||
|
}
|
||||||
|
|
||||||
resizeImage();
|
resizeImage();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -802,3 +839,22 @@ void ATVMod::getCameraNumbers(std::vector<int>& numbers)
|
|||||||
getOutputMessageQueue()->push(report);
|
getOutputMessageQueue()->push(report);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ATVMod::mixImageAndText(cv::Mat& image)
|
||||||
|
{
|
||||||
|
int fontFace = cv::FONT_HERSHEY_PLAIN;
|
||||||
|
double fontScale = image.rows / 100.0;
|
||||||
|
int thickness = 3;
|
||||||
|
int baseline=0;
|
||||||
|
|
||||||
|
qDebug("ATVMod::mixImageAndText: fontScale: %f m_overlayText: %s", fontScale, m_overlayText.c_str());
|
||||||
|
|
||||||
|
cv::Size textSize = cv::getTextSize(m_overlayText, fontFace, fontScale, thickness, &baseline);
|
||||||
|
baseline += thickness;
|
||||||
|
|
||||||
|
// position the text in the top left corner
|
||||||
|
cv::Point textOrg(2, textSize.height+4);
|
||||||
|
// then put the text itself
|
||||||
|
cv::putText(image, m_overlayText, textOrg, fontFace, fontScale, cv::Scalar::all(255*m_running.m_uniformLevel), thickness, CV_AA);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -256,6 +256,48 @@ public:
|
|||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class MsgConfigureOverlayText : public Message
|
||||||
|
{
|
||||||
|
MESSAGE_CLASS_DECLARATION
|
||||||
|
|
||||||
|
public:
|
||||||
|
const QString& getOverlayText() const { return m_overlayText; }
|
||||||
|
|
||||||
|
static MsgConfigureOverlayText* create(const QString& overlayText)
|
||||||
|
{
|
||||||
|
return new MsgConfigureOverlayText(overlayText);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString m_overlayText;
|
||||||
|
|
||||||
|
MsgConfigureOverlayText(const QString& overlayText) :
|
||||||
|
Message(),
|
||||||
|
m_overlayText(overlayText)
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
|
||||||
|
class MsgConfigureShowOverlayText : public Message
|
||||||
|
{
|
||||||
|
MESSAGE_CLASS_DECLARATION
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool getShowOverlayText() const { return m_showOverlayText; }
|
||||||
|
|
||||||
|
static MsgConfigureShowOverlayText* create(bool showOverlayText)
|
||||||
|
{
|
||||||
|
return new MsgConfigureShowOverlayText(showOverlayText);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool m_showOverlayText;
|
||||||
|
|
||||||
|
MsgConfigureShowOverlayText(bool showOverlayText) :
|
||||||
|
Message(),
|
||||||
|
m_showOverlayText(showOverlayText)
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
|
||||||
ATVMod();
|
ATVMod();
|
||||||
~ATVMod();
|
~ATVMod();
|
||||||
|
|
||||||
@ -452,7 +494,8 @@ private:
|
|||||||
Real m_peakLevel;
|
Real m_peakLevel;
|
||||||
Real m_levelSum;
|
Real m_levelSum;
|
||||||
|
|
||||||
cv::Mat m_imageOriginal; //!< original non resized image
|
cv::Mat m_imageFromFile; //!< original image not resized not overlaid by text
|
||||||
|
cv::Mat m_imageOriginal; //!< original not resized image
|
||||||
cv::Mat m_image; //!< resized image for transmission at given rate
|
cv::Mat m_image; //!< resized image for transmission at given rate
|
||||||
bool m_imageOK;
|
bool m_imageOK;
|
||||||
|
|
||||||
@ -474,6 +517,9 @@ private:
|
|||||||
std::vector<ATVCamera> m_cameras; //!< vector of available cameras
|
std::vector<ATVCamera> m_cameras; //!< vector of available cameras
|
||||||
int m_cameraIndex; //!< curent camera index in list of available cameras
|
int m_cameraIndex; //!< curent camera index in list of available cameras
|
||||||
|
|
||||||
|
std::string m_overlayText;
|
||||||
|
bool m_showOverlayText;
|
||||||
|
|
||||||
static const float m_blackLevel;
|
static const float m_blackLevel;
|
||||||
static const float m_spanLevel;
|
static const float m_spanLevel;
|
||||||
static const int m_levelNbSamples;
|
static const int m_levelNbSamples;
|
||||||
@ -496,6 +542,7 @@ private:
|
|||||||
void calculateCamerasSizes();
|
void calculateCamerasSizes();
|
||||||
void resizeCameras();
|
void resizeCameras();
|
||||||
void resizeCamera();
|
void resizeCamera();
|
||||||
|
void mixImageAndText(cv::Mat& image);
|
||||||
|
|
||||||
inline void pullImageLine(Real& sample)
|
inline void pullImageLine(Real& sample)
|
||||||
{
|
{
|
||||||
|
@ -324,6 +324,18 @@ void ATVModGUI::on_camSelect_currentIndexChanged(int index)
|
|||||||
m_atvMod->getInputMessageQueue()->push(message);
|
m_atvMod->getInputMessageQueue()->push(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ATVModGUI::on_overlayTextShow_toggled(bool checked)
|
||||||
|
{
|
||||||
|
ATVMod::MsgConfigureShowOverlayText* message = ATVMod::MsgConfigureShowOverlayText::create(checked);
|
||||||
|
m_atvMod->getInputMessageQueue()->push(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ATVModGUI::on_overlayText_textEdited(const QString& arg1)
|
||||||
|
{
|
||||||
|
ATVMod::MsgConfigureOverlayText* message = ATVMod::MsgConfigureOverlayText::create(ui->overlayText->text());
|
||||||
|
m_atvMod->getInputMessageQueue()->push(message);
|
||||||
|
}
|
||||||
|
|
||||||
void ATVModGUI::configureImageFileName()
|
void ATVModGUI::configureImageFileName()
|
||||||
{
|
{
|
||||||
qDebug() << "ATVModGUI::configureImageFileName: " << m_imageFileName.toStdString().c_str();
|
qDebug() << "ATVModGUI::configureImageFileName: " << m_imageFileName.toStdString().c_str();
|
||||||
|
@ -77,6 +77,9 @@ private slots:
|
|||||||
void on_playCamera_toggled(bool checked);
|
void on_playCamera_toggled(bool checked);
|
||||||
void on_camSelect_currentIndexChanged(int index);
|
void on_camSelect_currentIndexChanged(int index);
|
||||||
|
|
||||||
|
void on_overlayTextShow_toggled(bool checked);
|
||||||
|
void on_overlayText_textEdited(const QString& arg1);
|
||||||
|
|
||||||
void onWidgetRolled(QWidget* widget, bool rollDown);
|
void onWidgetRolled(QWidget* widget, bool rollDown);
|
||||||
void onMenuDoubleClicked();
|
void onMenuDoubleClicked();
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>386</width>
|
<width>491</width>
|
||||||
<height>364</height>
|
<height>364</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
@ -39,7 +39,7 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>10</x>
|
<x>10</x>
|
||||||
<y>10</y>
|
<y>10</y>
|
||||||
<width>360</width>
|
<width>461</width>
|
||||||
<height>341</height>
|
<height>341</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
@ -421,6 +421,50 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="ButtonSwitch" name="overlayTextShow">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>24</width>
|
||||||
|
<height>24</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Activate text overlay</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>T</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="overlayText">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>110</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>110</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Text overlay</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="maxLength">
|
||||||
|
<number>12</number>
|
||||||
|
</property>
|
||||||
|
<property name="cursorPosition">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<spacer name="horizontalSpacer_3">
|
<spacer name="horizontalSpacer_3">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
|
Loading…
Reference in New Issue
Block a user