- we can now save jpg screenshots and can also convert model textures to jpg (WARNING jpg DOES NOT support alpha channel (for transparency) so use this wisely

This commit is contained in:
Mark Vejvoda 2011-03-13 22:43:44 +00:00
parent b3951b3940
commit 28f74a15f7
6 changed files with 169 additions and 10 deletions

View File

@ -781,9 +781,9 @@ void MainWindow::saveScreenshot() {
string path = screenShotsPath;
if(isdir(path.c_str()) == true) {
//Config &config= Config::getInstance();
//string fileFormat = config.getString("ScreenShotFileType","png");
string fileFormat = "png";
Config &config= Config::getInstance();
string fileFormat = config.getString("ScreenShotFileType","png");
//string fileFormat = "png";
for(int i=0; i < 5000; ++i) {
path = screenShotsPath;

View File

@ -2,7 +2,7 @@
#include "graphics_factory_gl.h"
#include "graphics_interface.h"
#include <png.h>
//#include <png.h>
#include <memory>
using namespace Shared::Graphics;

View File

@ -865,13 +865,13 @@ void printParameterHelp(const char *argv0, bool foundInvalidArgs) {
printf("\n%s=x=textureformat=keepsmallest\t\t\tconvert a model file or folder to the current g3d version format.",GAME_ARGS[GAME_ARG_CONVERT_MODELS]);
printf("\n \t\tWhere x is a filename or folder containing the g3d model(s).");
printf("\n \t\tWhere textureformat is an optional supported texture format to convert to (tga,bmp,png).");
printf("\n \t\tWhere textureformat is an optional supported texture format to convert to (tga,bmp,jpg,png).");
printf("\n \t\tWhere keepsmallest is an optional flag indicating to keep original texture if its filesize is smaller than the converted format.");
printf("\n \t\texample: %s %s=techs/megapack/factions/tech/units/castle/models/castle.g3d=png=keepsmallest",argv0,GAME_ARGS[GAME_ARG_CONVERT_MODELS]);
printf("\n%s=x=textureformat\t\t\tconvert a texture file or folder to the format textureformat.",GAME_ARGS[GAME_ARG_CONVERT_TEXTURES]);
printf("\n \t\tWhere x is a filename or folder containing the texture(s).");
printf("\n \t\tWhere textureformat is a supported texture format to convert to (tga,bmp,png).");
printf("\n \t\tWhere textureformat is a supported texture format to convert to (tga,bmp,jpg,png).");
printf("\n \t\texample: %s %s=data/core/misc_textures/fire_particle.tga=png",argv0,GAME_ARGS[GAME_ARG_CONVERT_TEXTURES]);
printf("\n%s\t\tdisables stack backtrace on errors.",GAME_ARGS[GAME_ARG_DISABLE_BACKTRACE]);

View File

@ -116,6 +116,23 @@ public:
virtual void write(uint8 *pixels);
};
class PixmapIoJpg: public PixmapIo {
private:
FILE *file;
string path;
public:
PixmapIoJpg();
virtual ~PixmapIoJpg();
virtual void openRead(const string &path);
virtual void read(uint8 *pixels);
virtual void read(uint8 *pixels, int components);
virtual void openWrite(const string &path, int w, int h, int components);
virtual void write(uint8 *pixels);
};
// =====================================================
// class Pixmap1D
// =====================================================
@ -179,6 +196,7 @@ public:
void saveBmp(const string &path);
void saveTga(const string &path);
void savePng(const string &path);
void saveJpg(const string &path);
//get
int getW() const {return w;}

View File

@ -568,9 +568,17 @@ void Mesh::save(int meshIndex, const string &dir, FILE *f, TextureManager *textu
textureDeleteList[file] = textureDeleteList[file] + 1;
}
}
//else if(convertTextureToFormat == "jpg") {
// texture->getPixmap()->saveJpg(file);
//}
else if(convertTextureToFormat == "jpg") {
texture->getPixmap()->saveJpg(file);
newSize = getFileSize(file);
if(keepsmallest == false || newSize <= originalSize) {
textureDeleteList[texture->getPath()] = textureDeleteList[texture->getPath()] + 1;
}
else {
printf("Texture will not be converted, keeping smallest texture [%s]\n",texture->getPath().c_str());
textureDeleteList[file] = textureDeleteList[file] + 1;
}
}
else if(convertTextureToFormat == "png") {
texture->getPixmap()->savePng(file);
newSize = getFileSize(file);

View File

@ -22,6 +22,7 @@
#include "FileReader.h"
#include "ImageReaders.h"
#include <png.h>
#include <jpeglib.h>
#include <setjmp.h>
#include <memory>
@ -559,6 +560,128 @@ void PixmapIoPng::write(uint8 *pixels) {
*/
}
// =====================================================
// class PixmapIoJpg
// =====================================================
PixmapIoJpg::PixmapIoJpg() {
file= NULL;
}
PixmapIoJpg::~PixmapIoJpg() {
if(file!=NULL){
fclose(file);
file=NULL;
}
}
void PixmapIoJpg::openRead(const string &path) {
throw runtime_error("PixmapIoJpg::openRead not implemented!");
}
void PixmapIoJpg::read(uint8 *pixels) {
throw runtime_error("PixmapIoJpg::read not implemented!");
}
void PixmapIoJpg::read(uint8 *pixels, int components) {
throw runtime_error("PixmapIoJpg::read #2 not implemented!");
}
void PixmapIoJpg::openWrite(const string &path, int w, int h, int components) {
this->path = path;
this->w= w;
this->h= h;
this->components= components;
file= fopen(path.c_str(),"wb");
if (file == NULL) {
throw runtime_error("Can't open JPG file for writing: "+ path);
}
}
void PixmapIoJpg::write(uint8 *pixels) {
/*
* alpha channel is not supported for jpeg. strip it.
*/
unsigned char * tmpbytes = NULL;
if(components == 4) {
int n = w * h;
unsigned char *dst = tmpbytes = (unsigned char *) malloc(n*3);
const unsigned char *src = pixels;
for (int i = 0; i < n; i++) {
*dst++ = *src++;
*dst++ = *src++;
*dst++ = *src++;
src++;
}
components = 3;
}
struct jpeg_compress_struct cinfo;
struct jpeg_error_mgr jerr;
/* this is a pointer to one row of image data */
JSAMPROW row_pointer[1];
cinfo.err = jpeg_std_error( &jerr );
jpeg_create_compress(&cinfo);
jpeg_stdio_dest(&cinfo, file);
/* Setting the parameters of the output file here */
cinfo.image_width = w;
cinfo.image_height = h;
cinfo.input_components = 3; // no alpha channel for jpeg
cinfo.in_color_space = JCS_RGB;
/* default compression parameters, we shouldn't be worried about these */
jpeg_set_defaults( &cinfo );
/* Now do the compression .. */
jpeg_start_compress( &cinfo, TRUE );
/* use stripped alpha channel bytes */
if(tmpbytes) {
pixels = tmpbytes;
}
// OpenGL writes from bottom to top.
// libjpeg goes from top to bottom.
// flip lines.
uint8 *flip = (uint8 *)malloc(sizeof(uint8) * w * h * 3);
for (int y = 0;y < h; ++y) {
for (int x = 0;x < w; ++x) {
flip[(y * w + x) * 3] = pixels[((h - 1 - y) * w + x) * 3];
flip[(y * w + x) * 3 + 1] = pixels[((h - 1 - y) * w + x) * 3 + 1];
flip[(y * w + x) * 3 + 2] = pixels[((h - 1 - y) * w + x) * 3 + 2];
}
}
/* like reading a file, this time write one row at a time */
while( cinfo.next_scanline < cinfo.image_height ) {
row_pointer[0] = &flip[ cinfo.next_scanline * cinfo.image_width * cinfo.input_components];
jpeg_write_scanlines( &cinfo, row_pointer, 1 );
}
if (tmpbytes) {
free(tmpbytes);
tmpbytes=NULL;
}
free(flip);
flip=NULL;
/* similar to read file, clean up after we're done compressing */
jpeg_finish_compress( &cinfo );
jpeg_destroy_compress( &cinfo );
//fclose( outfile );
/* success code is 1! */
}
// =====================================================
// class Pixmap1D
// =====================================================
@ -774,6 +897,9 @@ void Pixmap2D::save(const string &path) {
else if(toLower(extension) == "tga") {
saveTga(path);
}
else if(toLower(extension) == "jpg") {
saveJpg(path);
}
else if(toLower(extension) == "png") {
savePng(path);
}
@ -793,12 +919,19 @@ void Pixmap2D::saveTga(const string &path) {
pst.openWrite(path, w, h, components);
pst.write(pixels);
}
void Pixmap2D::saveJpg(const string &path) {
PixmapIoJpg pst;
pst.openWrite(path, w, h, components);
pst.write(pixels);
}
void Pixmap2D::savePng(const string &path) {
PixmapIoPng pst;
pst.openWrite(path, w, h, components);
pst.write(pixels);
}
void Pixmap2D::getPixel(int x, int y, uint8 *value) const {
for(int i=0; i<components; ++i){
value[i]= pixels[(w*y+x)*components+i];