Saving a JPG from a BMP using GDI+ with a set DPI - jpeg

I have an image in BMP form and I want a C++ program to save it to JPG using GDI+, after reading some GDI+ documentation I came up with this program:
#include <windows.h>
#include <objidl.h>
#include <gdiplus.h>
#include "GdiplusHelperFunctions.h"
#pragma comment (lib,"Gdiplus.lib")
VOID SaveFile()
{
// Initialize GDI+.
Gdiplus::GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
CLSID encoderClsid;
Status stat;
EncoderParameters encoderParameters;
ULONG quality;
Image* image = new Gdiplus::Image(L"plot.bmp");
// Get the CLSID of the PNG encoder.
GetEncoderClsid(L"image/jpeg", &encoderClsid);
encoderParameters.Count = 1;
encoderParameters.Parameter[0].Guid = EncoderQuality;
encoderParameters.Parameter[0].Type = EncoderParameterValueTypeLong;
encoderParameters.Parameter[0].NumberOfValues = 1;
quality = 100;
encoderParameters.Parameter[0].Value = &quality;
stat = image->Save(L"plot100.jpg", &encoderClsid, &encoderParameters);
if (stat == Ok)
printf("plot.jpg was saved successfully\n");
else
printf("Failure: stat = %d\n", stat);
delete image;
GdiplusShutdown(gdiplusToken);
return;
}
int main()
{
SaveFile();
return 0;
}
But the image is saving with a horizontal and vertical resolution of 7dpi no matter what the value of "quelity" is, I need to save the jpg with a 96dpi, how can I set that?
Thank you in advance.

A modified version of the function SaveFile() solved the problem:
VOID SaveFile()
{
// Initialize GDI+.
Gdiplus::GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
CLSID encoderClsid;
Status stat;
EncoderParameters encoderParameters;
ULONG quality;
Gdiplus::Bitmap* bitmap = new Gdiplus::Bitmap(L"plot.bmp");
Gdiplus::REAL dpi = 72;
bitmap->SetResolution(dpi,dpi);
// Get the CLSID of the PNG encoder.
GetEncoderClsid(L"image/jpeg", &encoderClsid);
encoderParameters.Count = 1;
encoderParameters.Parameter[0].Guid = EncoderQuality;
encoderParameters.Parameter[0].Type = EncoderParameterValueTypeLong;
encoderParameters.Parameter[0].NumberOfValues = 1;
quality = 100;
encoderParameters.Parameter[0].Value = &quality;
stat = bitmap->Save(L"plot.jpg", &encoderClsid, &encoderParameters);
if (stat == Ok)
printf("plot.jpg was saved successfully\n");
else
printf("Failure: stat = %d\n", stat);
delete bitmap;
GdiplusShutdown(gdiplusToken);
return;
}

Related

How to capture a certain region of screen

Ihave to record a certain area of a screen and save the frames (20-30fps) of the video being played. Currently I'm able to capture the screen at the required frame rate using the following code, However I'm not really sure about how I can capture a certain region.
HRESULT SavePixelsToFile32bppPBGRA(UINT width, UINT height, UINT stride, BYTE, *pixels, LPWSTR filePath, const GUID &format)
{
if (!filePath || !pixels)
return E_INVALIDARG;
HRESULT hr = S_OK;
IWICImagingFactory *factory = nullptr;
IWICBitmapEncoder *encoder = nullptr;
IWICBitmapFrameEncode *frame = nullptr;
IWICStream *stream = nullptr;
GUID pf = GUID_WICPixelFormat32bppPBGRA;
BOOL coInit = CoInitialize(nullptr);
CoCreateInstance(CLSID_WICImagingFactory, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&factory));
factory->CreateStream(&stream);
stream->InitializeFromFilename(filePath, GENERIC_WRITE);
factory->CreateEncoder(format, nullptr, &encoder);
encoder->Initialize(stream, WICBitmapEncoderNoCache);
encoder->CreateNewFrame(&frame, nullptr); // we don't use options here
frame->Initialize(nullptr); // we dont' use any options here
frame->SetSize(width, height);
frame->SetPixelFormat(&pf);
frame->WritePixels(height, stride, stride * height, pixels);
frame->Commit();
encoder->Commit();
RELEASE(stream);
RELEASE(frame);
RELEASE(encoder);
RELEASE(factory);
if (coInit) CoUninitialize();
return hr;
}
HRESULT Direct3D9TakeScreenshots(UINT adapter, int count)
{
HRESULT hr = S_OK;
IDirect3D9 *d3d = nullptr;
IDirect3DDevice9 *device = nullptr;
IDirect3DSurface9 *surface = nullptr;
D3DPRESENT_PARAMETERS parameters = { 0 };
D3DDISPLAYMODE mode;
D3DLOCKED_RECT rc;
UINT pitch;
SYSTEMTIME st;
BYTE *shot = nullptr;
// init D3D and get screen size
d3d = Direct3DCreate9(D3D_SDK_VERSION);
d3d->GetAdapterDisplayMode(adapter, &mode);
parameters.Windowed = TRUE;
parameters.BackBufferCount = 1;
parameters.BackBufferHeight = mode.Height;
parameters.BackBufferWidth = mode.Width;
parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
parameters.hDeviceWindow = NULL;
// create device & capture surface
d3d->CreateDevice(adapter, D3DDEVTYPE_HAL, NULL, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &parameters, &device);
device->CreateOffscreenPlainSurface(mode.Width, mode.Height, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, nullptr);
// compute the required buffer size
surface->LockRect(&rc, NULL, 0);
pitch = rc.Pitch;
surface->UnlockRect();
// allocate screenshots buffers
shot = new BYTE[pitch * mode.Height];
// get the data
device->GetFrontBufferData(0, surface);
// copy it into our buffers
surface->LockRect(&rc, NULL, 0);
CopyMemory(shot, rc.pBits, rc.Pitch * mode.Height);
surface->UnlockRect();
WCHAR file[100];
wsprintf(file, L"C:/Frames/cap%i.png", count);
SavePixelsToFile32bppPBGRA(mode.Width, mode.Height, pitch, shot, file, GUID_ContainerFormatPng);
if (shot != nullptr)
{
delete shot;
}
RELEASE(surface);
RELEASE(device);
RELEASE(d3d);
return hr;
}
I know I can open the saved images and crop them and then again save them, but that will take up extra time. Is there a way to select a desired region

SDL2/SDL.h causing undefined references in Non-SDL code

I've been having an awfully strange problem that I cannot seem to grasp. I'm almost convinced that this is a compiler bug.
xTech : xIncludes.hh
#ifndef _xIncludes_
#define _xIncludes_
#define SDL_MAIN_HANDLED
#include <string.h>
#include <stdio.h>
#include <stdarg.h>
#include <stdint.h>
#include <vector>
#include <SDL2/SDL.h>
#if defined _WIN32
#include <winsock.h>
#endif
#endif
xTech : xSound.cc
#include "xSound.hh"
int xOGGStreamSource::_stream(ALuint Buffer) {
char data[BufferSize];
int size = 0;
int section;
int result;
while (size < BufferSize) {
result = ov_read(&_oggstream, data + size, BufferSize - size, 0, 2, 1, &section);
if (result > 0)
size += result;
else
if (result < 0)
return result;
else
break; //This seems a little redundant.... deal with it after it works.
}
if (size == 0) return 0;
alBufferData(Buffer, _format, data, size, _vorbisinfo->rate);
return 1;
}
void xOGGStreamSource::_empty() {
int queued;
alGetSourcei(_source, AL_BUFFERS_QUEUED, &queued);
while (queued--) {
ALuint Buffer;
alSourceUnqueueBuffers(_source, 1, &Buffer);
}
}
int xOGGStreamSource::Open(xString path) {
int result;
_oggfile = xOpenFile(path, "rb");
if (_oggfile.Buffer == NULL) {
xLogf("Audio", "Error in OGG File '%s', file does not exist.", path);
return -3;
}
if (result = ov_open(_oggfile.Buffer, &_oggstream, NULL, 0) < 0) {
xLogf("Audio", "Error in OGG File '%s', file is non-OGG.", path);
xCloseFile(_oggfile);
return -2;
}
_vorbisinfo = ov_info(&_oggstream, -1);
_vorbiscomment = ov_comment(&_oggstream, -1);
if (_vorbisinfo->channels == 1)
_format = AL_FORMAT_MONO16;
else
_format = AL_FORMAT_STEREO16;
alGenBuffers(2, _buffers);
alGenSources(1, &_source);
return 1;
}
void xOGGStreamSource::Close() {
alSourceStop(_source);
_empty();
alDeleteSources(1, &_source);
alDeleteBuffers(1, _buffers);
ov_clear(&_oggstream);
}
int xOGGStreamSource::Playback() {
if (Playing()) return 1;
if (!_stream(_buffers[0])) return 0;
if (!_stream(_buffers[1])) return 0;
alSourceQueueBuffers(_source, 2, _buffers);
alSourcePlay(_source);
return 1;
}
int xOGGStreamSource::Playing() {
ALenum state;
alGetSourcei(_source, AL_SOURCE_STATE, &state);
return (state == AL_PLAYING);
}
int xOGGStreamSource::Update(xVec3f_t Pos, xVec3f_t Vloc, xVec3f_t Dir, float Vol) {
int processed;
int active = 1;
alSource3f(_source, AL_POSITION, Pos.X, Pos.Y, Pos.Z);
alSource3f(_source, AL_VELOCITY, Vloc.X, Vloc.Y, Vloc.Z);
alSource3f(_source, AL_DIRECTION, Dir.X, Dir.Y, Dir.Z);
alSourcef (_source, AL_GAIN, Vol);
alSourcei (_source, AL_SOURCE_RELATIVE, AL_TRUE);
alGetSourcei(_source, AL_BUFFERS_PROCESSED, &processed);
while(processed--) {
ALuint Buffer;
alSourceUnqueueBuffers(_source, 1, &Buffer);
active = _stream(Buffer);
alSourceQueueBuffers(_source, 1, &Buffer);
}
return active;
}
xSound::xSound(xOGGStreamSource xss) { _source = xss; }
int xSound::PlaySound(float Volume, xVec3f_t Location) {
if (!_source.Playback()) return -3;
while(_source.Update(Location, xVec3f_t(0,0,0), xVec3f_t(0,0,0), Volume)) {
if (!_source.Playing()) {
if (!_source.Playback()) return -2;
else return -1;
}
}
_source.Close();
return 1;
}
xSoundManager::xSoundManager(){}
int xSoundManager::Init() {
_device = alcOpenDevice(NULL);
if (!_device) return -2;
_context = alcCreateContext(_device, NULL);
if (alcMakeContextCurrent(_context) == ALC_FALSE || !_context) return -1;
if (!Volume) {
xLogf("Error", "Volume in Audio is not set properly. Setting to default");
Volume = DEFAULT_VOLUME;
}
alListenerf(AL_GAIN, Volume);
if (!BufferSize) {
xLogf("Error", "Buffer size in Audio is not set properly. Setting to default");
BufferSize = DEFAULT_BUFFER_SIZE;
}
return 0;
}
xSound* xSoundManager::LoadOGG(xString file) {
xOGGStreamSource ogg;
if (ogg.Open(file) < 0) return NULL;
return new xSound(ogg);
}
xTechLibTest : main.cc
int main() {
xSetLogFile("xTechLibTest.log");
xSoundManager* audio = new xSoundManager();
if (audio->Init() < 0) return -1;
xSound* testsound1 = audio->LoadOGG("testsound.ogg");
if (testsound1 == NULL) return -2;
testsound1->PlaySound(1.0, xVec3f_t(1.0,0.5,0.3));
}
The above code and everything associated with it (string implementations, etc) work fine, no problems at all. That is until I include SDL.h; I get undefined references for every function I defined, when the compiler could find them with no problem before. It seems that the mere inclusion of SDL.h completely nullifies any definition I make. Any ideas what's going on here?
Have you properly included the linkage to the SDL libraries?
If you have built the binaries yourself, you need to include the path and library. On a linux system, if you have built the static libraries yourself, you will have a binary called libSDL2.a, however to link you need to specify SDL2 as your linked library.
Also as a side note, do you have a redundant include guard on your xsound.h file( via #ifdef _xsound_ ... ) ?
p.s. It will help the other users if you specify what how your environment is setup; compiler, system os, IDE.
It would be useful to see the output from your compiler/linker.
I've had similar problems with network related code when using Cygwin on a windows machine. I've had sockets working fine without SDL, as soon as I include SDL, the whole lot breaks with messages saying that certain header files and references can't be found.
I'm not certain, but I think it has something to do with the way that SDL has it's own main macros (here is a post about it here - simple tcp echo program not working when SDL included?).
I may be wrong, but is this similar to what you are seeing?

How to play and detect an object using captured video in background subtractor model?

everyone.! I am using opencv2.4.2. actually I am doing project on object detection. I tried using BackgroundSubtractorMOG model.
But I am not able to load video file from my computer. While running on real time this below code for segmentation works fine.
I have implemented using frame differencing method for object detection. Now I want to segment whole object from the background. I have static background. so can anybody help me in below code how to segment object from captured video. also how to load a video file?
thank you.
#include "stdafx.h"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/contrib/contrib.hpp"
#include "conio.h"
#include "time.h"
#include "opencv/cvaux.hpp"
#include "opencv2/core/core.hpp"
#include "opencv2/calib3d/calib3d.hpp"
using namespace std;
using namespace cv;
int main(int argc, char** argv)
{
//IplImage* tmp_frame;
//std::string arg = argv[1];
//VideoCapture capture();
cv::VideoCapture cap;
/*CvCapture *cap =cvCaptureFromFile("S:\\offline object detection database\\SINGLE PERSON Database\\video4.avi");
if(!cap){
printf("Capture failure\n");
return -1;
}
IplImage* frame=0;
frame = cvQueryFrame(cap);
if(!frame)
return -1;*/
bool update_bg_model = true;
if( argc < 2 )
cap.open(0);
else
cap.open(std::string(argv[1]));
if( !cap.isOpened() )
{
printf("can not open camera or video file\n");
return -1;
}
Mat tmp_frame, bgmask;
cap >> tmp_frame;
if(!tmp_frame.data)
{
printf("can not read data from the video source\n");
return -1;
}
namedWindow("video", 1);
namedWindow("segmented", 1);
BackgroundSubtractorMOG bgsubtractor;
for(;;)
{
//double t = (double)cvGetTickCount();
cap >> tmp_frame;
if( !tmp_frame.data )
break;
bgsubtractor(tmp_frame, bgmask, update_bg_model ? -1 : 0);
//t = (double)cvGetTickCount() - t;
//printf( "%d. %.1f\n", fr, t/(cvGetTickFrequency()*1000.) );
imshow("video", tmp_frame);
imshow("segmented", bgmask);
char keycode = waitKey(30);
if( keycode == 27 ) break;
if( keycode == ' ' )
update_bg_model = !update_bg_model;
}
return 0;
}
The video loading in opencv works for me. To load a video you can try something like this. Once you have captured frame you either do processing in the loop or can call a separate function.
std::cout<<"Video File "<<argv[1]<<std::endl;
cv::VideoCapture input_video(argv[1]);
namedWindow("My_Win",1);
Mat cap_img;
while(input_video.grab())
{
if(input_video.retrieve(cap_img))
{
imshow("My_Win", cap_img);
/* Once you have the image do all the processing here */
/* Or Call your image processing function */
waitKey(1);
}
}
or You can do something
int main(int argc, char*argv[])
{
char *my_file = "C:\\vid_an2\\desp_me.avi";
std::cout<<"Video File "<<my_file<<std::endl;
cv::VideoCapture input_video;
if(input_video.open(my_file))
{
std::cout<<"Video file open "<<std::endl;
}
else
{
std::cout<<"Not able to Video file open "<<std::endl;
}
namedWindow("My_Win",1);
namedWindow("Segemented", 1);
Mat cap_img;
for(;;)
{
input_video >> cap_img;
imshow("My_Win", cap_img);
waitKey(0);
}
return 0;
}

Qt - how to save my QTableView as a Excel File?

Can anyone plz help me, how to save my QtableView as a Excel File. I have a QTableView and a QPushButton (Save Button). If i enter the values in my QtableView and if i click the Save Buttton the QTableView items should be saved as Excel File. Plz Help me. Thanks..
Have a look at this thread My-approach-to-export-QTableView-data-to-a-Microsoft-Excel-file. I got this link by asking Google for: QTableView save. For the solution there you need a Qt with ODBC enabled which is not the default.
You can also study the fine documentation that contains e.g. an Address Book Example that includes a writeToFile function. You can start from there and search e.g. for information about the CSV format.
this link worked for me :
http://www.qtcn.org/bbs/simple/?t47265.html
1-you should also use below code in .pro file.
QT += sql
2-you should use #include "exportexcelobject.h" in your file that wanna export to excel.
See the code sample:
ExcelExportHelper.h
#ifndef EXCELHELPER_H
#define EXCELHELPER_H
#include <ActiveQt/qaxobject.h>
#include <ActiveQt/qaxbase.h>
#include <QString>
//Expected in .pro file: QT += axcontainer
//Application must be of UI type for ActiveX work.
class ExcelExportHelper
{
public:
ExcelExportHelper(const ExcelExportHelper& other) = delete;
ExcelExportHelper& operator=(const ExcelExportHelper& other) = delete;
ExcelExportHelper(bool closeExcelOnExit = false);
void SetCellValue(int lineIndex, int columnIndex, const QString& value);
void SaveAs(const QString& fileName);
~ExcelExportHelper();
private:
QAxObject* m_excelApplication;
QAxObject* m_workbooks;
QAxObject* m_workbook;
QAxObject* m_sheets;
QAxObject* m_sheet;
bool m_closeExcelOnExit;
};
#endif // EXCELHELPER_H
ExcelExportHelper.cpp
#include <ActiveQt/qaxobject.h>
#include <ActiveQt/qaxbase.h>
#include <QString>
#include <QFile>
#include <stdexcept>
using namespace std;
#include "ExcelExportHelper.h"
ExcelExportHelper::ExcelExportHelper(bool closeExcelOnExit)
{
m_closeExcelOnExit = closeExcelOnExit;
m_excelApplication = nullptr;
m_sheet = nullptr;
m_sheets = nullptr;
m_workbook = nullptr;
m_workbooks = nullptr;
m_excelApplication = nullptr;
m_excelApplication = new QAxObject( "Excel.Application", 0 );//{00024500-0000-0000-C000-000000000046}
if (m_excelApplication == nullptr)
throw invalid_argument("Failed to initialize interop with Excel (probably Excel is not installed)");
m_excelApplication->dynamicCall( "SetVisible(bool)", false ); // hide excel
m_excelApplication->setProperty( "DisplayAlerts", 0); // disable alerts
m_workbooks = m_excelApplication->querySubObject( "Workbooks" );
m_workbook = m_workbooks->querySubObject( "Add" );
m_sheets = m_workbook->querySubObject( "Worksheets" );
m_sheet = m_sheets->querySubObject( "Add" );
}
void ExcelExportHelper::SetCellValue(int lineIndex, int columnIndex, const QString& value)
{
QAxObject *cell = m_sheet->querySubObject("Cells(int,int)", lineIndex, columnIndex);
cell->setProperty("Value",value);
delete cell;
}
void ExcelExportHelper::SaveAs(const QString& fileName)
{
if (fileName == "")
throw invalid_argument("'fileName' is empty!");
if (fileName.contains("/"))
throw invalid_argument("'/' character in 'fileName' is not supported by excel!");
if (QFile::exists(fileName))
{
if (!QFile::remove(fileName))
{
throw new exception(QString("Failed to remove file '%1'").arg(fileName).toStdString().c_str());
}
}
m_workbook->dynamicCall("SaveAs (const QString&)", fileName);
}
ExcelExportHelper::~ExcelExportHelper()
{
if (m_excelApplication != nullptr)
{
if (!m_closeExcelOnExit)
{
m_excelApplication->setProperty("DisplayAlerts", 1);
m_excelApplication->dynamicCall("SetVisible(bool)", true );
}
if (m_workbook != nullptr && m_closeExcelOnExit)
{
m_workbook->dynamicCall("Close (Boolean)", true);
m_excelApplication->dynamicCall("Quit (void)");
}
}
delete m_sheet;
delete m_sheets;
delete m_workbook;
delete m_workbooks;
delete m_excelApplication;
}
Usage:
try
{
const QString fileName = "g:\\temp\\kaka2.xlsx";
ExcelExportHelper helper;
helper.SetCellValue(1,1,"Test-11");
helper.SetCellValue(1,2,"Test-12");
helper.SaveAs(fileName);
}
catch (const exception& e)
{
QMessageBox::critical(this, "Error - Demo", e.what());
}

how to convert byte* into jpeg file in VC++

how to convert byte* into jpeg file in VC++
i am capturing Video samples and writing it as bmp files, but i want to write that video samples into jpeg file using MFC support in ATL COM.
Use libjpg. Download from: http://www.ijg.org/
From what it appears, you have the image data in a buffer pointed to by a byte object. Note, that the type actually is BYTE (all uppercase). If the data is in JPEG format already why don't you write that data out to a file (with a suitable '.jpg' or '.jpeg' extension) and try loading it with an image editor? Otherwise, you will need to decode that to raw format and encode in the JPEG format.
Or, you need to explain you problem in more detail, preferably with some code.
Raw image data to JPEG can be acheived by ImageMagick.
You may also try to use CxImage C++ class to save your stills to JPEG-encoded file.
There are some more Windows API oriented alternatives available on CodeProject, for instance CMiniJpegEncoder
It is even possible to render JPEG to file from Windows bitmap using libgd library if compiled with libjpeg support. Here is code of small extension function gdImageTrueColorAttachBuffer I developed for this purpose some time ago:
// libgd ext// libgd extension by Mateusz Loskot <mateusz at loskot dot net>
// Originally developed for Windows CE to enable direct drawing
// on Windows API Device Context using libgd API.
// Complete example available in libgd CVS:
// http://cvs.php.net/viewvc.cgi/gd/libgd/examples/windows.c?diff_format=u&revision=1.1&view=markup
//
gdImagePtr gdImageTrueColorAttachBuffer(int* buffer, int sx, int sy, int stride)
{
int i;
int height;
int* rowptr;
gdImagePtr im;
im = (gdImage *) malloc (sizeof (gdImage));
if (!im) {
return 0;
}
memset (im, 0, sizeof (gdImage));
#if 0
if (overflow2(sizeof (int *), sy)) {
return 0;
}
#endif
im->tpixels = (int **) malloc (sizeof (int *) * sy);
if (!im->tpixels) {
free(im);
return 0;
}
im->polyInts = 0;
im->polyAllocated = 0;
im->brush = 0;
im->tile = 0;
im->style = 0;
height = sy;
rowptr = buffer;
if (stride < 0) {
int startoff = (height - 1) * stride;
rowptr = buffer - startoff;
}
i = 0;
while (height--) {
im->tpixels[i] = rowptr;
rowptr += stride;
i++;
}
im->sx = sx;
im->sy = sy;
im->transparent = (-1);
im->interlace = 0;
im->trueColor = 1;
im->saveAlphaFlag = 0;
im->alphaBlendingFlag = 1;
im->thick = 1;
im->AA = 0;
im->cx1 = 0;
im->cy1 = 0;
im->cx2 = im->sx - 1;
im->cy2 = im->sy - 1;
return im;
}
void gdSaveJPEG(void* bits, int width, int height, const char* filename)
{
bool success = false;
int stride = ((width * 1 + 3) >> 2) << 2;
gdImage* im = gdImageTrueColorAttachBuffer((int*)bits, width, height, -stride);
if (0 != im)
{
FILE* jpegout = fopen(filename, "wb");
gdImageJpeg(im, jpegout, -1);
fclose(jpegout);
success = true;
}
gdImageDestroy(im);
return success;
}
I hope it helps.

Resources