2012-02-01 7 views
20

का उपयोग करने के उदाहरण या ट्यूटोरियल libjpeg-turbo here के लिए निर्देश इस प्रकार टर्बोजेपीईजी एपीआई का वर्णन करते हैं: "यह एपीआई libjpeg-turbo wraps और स्मृति में जेपीईजी छवियों को संपीड़ित और डिकंप्रेस करने के लिए उपयोग में आसान इंटरफ़ेस प्रदान करता है" । बढ़िया है, लेकिन क्या इस एपीआई का उपयोग करने के कुछ ठोस उदाहरण उपलब्ध हैं? बस स्मृति में एक काफी वेनिला जेपीजी डिकंप्रेस करने के लिए देख रहे हैं।libjpeg-turbo के TurboJPEG

मुझे कुछ बिट्स जैसे https://github.com/erlyvideo/jpeg/blob/master/c_src/jpeg.c मिल गए हैं, जो टर्बोजेपीईजी एपीआई का उपयोग कर रहे हैं, लेकिन क्या कोई और ठोस/विविध उदाहरण हैं?

libjpeg-turbo का स्रोत अच्छी तरह से प्रलेखित है, इसलिए इससे मदद मिलती है।

उत्तर

4

अंत में मैं (जैसे https://github.com/erlyvideo/jpeg/blob/master/c_src/jpeg.c) यादृच्छिक कोड इंटरनेट पर पाए और libjeg-टर्बो के लिए ग और हेडर फाइल है, जो अच्छी तरह से प्रलेखित रहे हैं का एक संयोजन का इस्तेमाल किया। This आधिकारिक एपीआई एक अच्छी जानकारी स्रोत भी है।

+0

यदि कोड छोटा है तो आप इसे अपने उत्तर में सुधार के लिए यहां साझा कर सकते हैं;) –

+0

मैं इसे किसी बिंदु पर देखता हूं और उत्तर में जोड़ता हूं। – occulus

1

यहां कोड का एक टुकड़ा है जिसका उपयोग मैं जेपीईजी को स्मृति से लोड करने के लिए करता हूं। शायद इसे कुछ फिक्सिंग की आवश्यकता होगी, क्योंकि मैंने इसे अपनी परियोजना में विभिन्न फाइलों से निकाला है। यह दोनों - ग्रेस्केल और आरजीबी छवियों को लोड करेगा (बीपीपी या तो 1 या 3 तक सेट किया जाएगा)।

struct Image 
{ 
    int bpp; 
    int width; 
    int height; 
    unsigned char* data; 
}; 

struct jerror_mgr 
{ 
    jpeg_error_mgr base; 
    jmp_buf  jmp; 
}; 

METHODDEF(void) jerror_exit(j_common_ptr jinfo) 
{ 
    jerror_mgr* err = (jerror_mgr*)jinfo->err; 
    longjmp(err->jmp, 1); 
} 

METHODDEF(void) joutput_message(j_common_ptr) 
{ 
} 

bool Image_LoadJpeg(Image* image, unsigned char* img_data, unsigned int img_size) 
{ 
    jpeg_decompress_struct jinfo; 
    jerror_mgr jerr; 

    jinfo.err = jpeg_std_error(&jerr.base); 
    jerr.base.error_exit = jerror_exit; 
    jerr.base.output_message = joutput_message; 
    jpeg_create_decompress(&jinfo); 

    image->data = NULL; 

    if (setjmp(jerr.jmp)) goto bail; 

    jpeg_mem_src(&jinfo, img_data, img_size); 

    if (jpeg_read_header(&jinfo, TRUE) != JPEG_HEADER_OK) goto bail; 

    jinfo.dct_method = JDCT_FLOAT; // change this to JDCT_ISLOW on Android/iOS 

    if (!jpeg_start_decompress(&jinfo)) goto bail; 

    if (jinfo.num_components != 1 && jinfo.num_components != 3) goto bail; 

    image->data = new (std::nothrow) unsigned char [jinfo.output_width * jinfo.output_height * jinfo.output_components]; 
    if (!image->data) goto bail; 

    { 
     JSAMPROW ptr = image->data; 
     while (jinfo.output_scanline < jinfo.output_height) 
     { 
      if (jpeg_read_scanlines(&jinfo, &ptr, 1) != 1) goto bail; 

      ptr += jinfo.output_width * jinfo.output_components; 
     } 
    } 

    if (!jpeg_finish_decompress(&jinfo)) goto bail; 

    image->bpp = jinfo.output_components; 
    image->width = jinfo.output_width; 
    image->height = jinfo.output_height; 

    jpeg_destroy_decompress(&jinfo); 

    return true; 

bail: 
    jpeg_destroy_decompress(&jinfo); 
    if (image->data) delete [] data; 

    return false; 
} 
+1

क्षमा करें आपका जवाब unaccept के लिए, लेकिन मैं वास्तव में लागू करने कर रहा हूँ अब बारीकी से देख पर इस मैं आपको और कोड आप पोस्ट (जैसे tjDecompress) में TJ कार्यों बुला नहीं कर रहे हैं देख सकते हैं। – occulus

+0

libjpeg-turbo लाइब्रेरी से गति लाभ प्राप्त करने के लिए टर्बोजेपी एपीआई का उपयोग करना अनिवार्य नहीं है। मेरे उदाहरण में मैं केवल मानक libjpeg एपीआई का उपयोग कर रहा हूँ। आप libjpeg एपीआई का उपयोग क्यों नहीं करना चाहते हैं? –

+2

मेरा प्रश्न स्पष्ट रूप से TurboJPEG API के बारे में पूछ रहा है। मैं मानक libjpeg इंटरफ़ेस की तुलना में इसकी सादगी के कारण इसका उपयोग कर रहा हूं। – occulus

43

ठीक है, मुझे पता है कि आपने अपनी समस्या को पहले ही हल कर लिया है, लेकिन कुछ लोगों के रूप में, मेरे जैसे ही, कुछ सरल उदाहरण खोज सकते हैं जो मैंने बनाया है साझा करेंगे। यह एक उदाहरण है, एक आरजीबी छवि को संपीड़ित और डिकंप्रेस करना। अन्यथा मुझे लगता है कि TurboJPEG का एपीआई दस्तावेज समझने में काफी आसान है!

संपीड़न:

#include <turbojpeg.h> 

const int JPEG_QUALITY = 75; 
const int COLOR_COMPONENTS = 3; 
int _width = 1920; 
int _height = 1080; 
long unsigned int _jpegSize = 0; 
unsigned char* _compressedImage = NULL; //!< Memory is allocated by tjCompress2 if _jpegSize == 0 
unsigned char buffer[_width*_height*COLOR_COMPONENTS]; //!< Contains the uncompressed image 

tjhandle _jpegCompressor = tjInitCompress(); 

tjCompress2(_jpegCompressor, buffer, _width, 0, _height, TJPF_RGB, 
      &_compressedImage, &_jpegSize, TJSAMP_444, JPEG_QUALITY, 
      TJFLAG_FASTDCT); 

tjDestroy(_jpegCompressor); 

//to free the memory allocated by TurboJPEG (either by tjAlloc(), 
//or by the Compress/Decompress) after you are done working on it: 
tjFree(&_compressedImage); 

उसके बाद आप _compressedImage में संकुचित छवि है। को संपीड़ित करने के लिए आप निम्न क्या करना है:

विसंपीड़न:

#include <turbojpeg.h> 

long unsigned int _jpegSize; //!< _jpegSize from above 
unsigned char* _compressedImage; //!< _compressedImage from above 

int jpegSubsamp, width, height; 
unsigned char buffer[width*height*COLOR_COMPONENTS]; //!< will contain the decompressed image 

tjhandle _jpegDecompressor = tjInitDecompress(); 

tjDecompressHeader2(_jpegDecompressor, _compressedImage, _jpegSize, &width, &height, &jpegSubsamp); 

tjDecompress2(_jpegDecompressor, _compressedImage, _jpegSize, buffer, width, 0/*pitch*/, height, TJPF_RGB, TJFLAG_FASTDCT); 

tjDestroy(_jpegDecompressor); 

कुछ यादृच्छिक विचार:

मैं सिर्फ वापस इस पर आया था के रूप में मैं अपने स्नातक थीसिस लिख रहा हूँ, और मैंने देखा कि यदि आप एक लूप में संपीड़न चलाते हैं तो जेपीईजी बफर के सबसे बड़े आकार को स्टोर करने के लिए बेहतर है ताकि हर मोड़ को एक नया आवंटित न किया जा सके। मूल रूप से, बजाय करने का:

long unsigned int _jpegSize = 0; 

tjCompress2(_jpegCompressor, buffer, _width, 0, _height, TJPF_RGB, 
      &_compressedImage, &_jpegSize, TJSAMP_444, JPEG_QUALITY, 
      TJFLAG_FASTDCT); 

हम एक वस्तु चर जोड़ना होगा, आबंटित स्मृति long unsigned int _jpegBufferSize = 0; के आकार धारण और हर संपीड़न दौर से पहले हम उस मूल्य को वापस jpegSize स्थापित करेगा:

long unsigned int jpegSize = _jpegBufferSize; 

tjCompress2(_jpegCompressor, buffer, _width, 0, _height, TJPF_RGB, 
      &_compressedImage, &jpegSize, TJSAMP_444, JPEG_QUALITY, 
      TJFLAG_FASTDCT); 

_jpegBufferSize = _jpegBufferSize >= jpegSize? _jpegBufferSize : jpegSize; 

संपीड़न के बाद एक वास्तविक जेपीजी आकार के साथ स्मृति आकार की तुलना करेगा और इसे जेपीजी आकार में सेट करेगा यदि यह पिछले स्मृति आकार से अधिक है।

+1

यह अद्भुत है! धन्यवाद! – mousomer

+0

मैं कोशिश करूंगा। टर्बोजेप दस्तावेज कहता है कि यह पंक्ति की लंबाई होनी चाहिए। मुझे आउटपुट या इनपुट की समझ में नहीं आता है। वैसे भी, मुझे गलती हुई थी। आकार उचित हैं। वैसे - वर्तमान में मैं जेपीईजी (डीकंप्रेसिंग) लोड कर रहा हूं, और फ़ाइलों को फ़ाइलों में फसल कर रहा हूं। क्या छवि को क्रॉप करने और आउटपुट को फ़ाइल में भेजने के लिए एक टर्बोजेप 2-लाइनर है? – mousomer

+0

मैंने बस इतना किया - फसल वाले क्षेत्र लाइन-बाय-लाइन को एक बफर (लूप के लिए 2 लाइन), जेपीईजी संपीड़न (1 लाइन) और fstream (4 लाइनों) को लिखना। मैंने सोचा, शायद, पहले से ही एक पुस्तकालय समारोह पहले से ही कर रहा है। – mousomer

1

मैं जेपीईजी एन्कोडिंग और डिकोडिंग दोनों के लिए एक कामकाजी उदाहरण के रूप में नीचे कोड का उपयोग कर समाप्त हुआ। सबसे अच्छा उदाहरण जो मैं पा सकता हूं, यह स्वयं निहित है जो एक डमी छवि को प्रारंभ करता है और एन्कोडेड छवि को स्थानीय फ़ाइल में आउटपुट करता है।

नीचे कोड नहीं है, क्रेडिट https://sourceforge.net/p/libjpeg-turbo/discussion/1086868/thread/e402d36f/#8722 पर जाता है। किसी को भी मदद करने के लिए इसे फिर से पोस्ट करना यह पता चलता है कि libjpeg टर्बो काम करना मुश्किल है।

#include "turbojpeg.h" 
#include <iostream> 
#include <string.h> 
#include <errno.h> 

using namespace std; 

int main(void) 
{ 
    unsigned char *srcBuf; //passed in as a param containing pixel data in RGB pixel interleaved format 
    tjhandle handle = tjInitCompress(); 

    if(handle == NULL) 
    { 
     const char *err = (const char *) tjGetErrorStr(); 
     cerr << "TJ Error: " << err << " UNABLE TO INIT TJ Compressor Object\n"; 
     return -1; 
    } 
    int jpegQual =92; 
    int width = 128; 
    int height = 128; 
    int nbands = 3; 
    int flags = 0; 
    unsigned char* jpegBuf = NULL; 
    int pitch = width * nbands; 
    int pixelFormat = TJPF_GRAY; 
    int jpegSubsamp = TJSAMP_GRAY; 
    if(nbands == 3) 
    { 
     pixelFormat = TJPF_RGB; 
     jpegSubsamp = TJSAMP_411; 
    } 
    unsigned long jpegSize = 0; 

    srcBuf = new unsigned char[width * height * nbands]; 
    for(int j = 0; j < height; j++) 
    { 
     for(int i = 0; i < width; i++) 
     { 
      srcBuf[(j * width + i) * nbands + 0] = (i) % 256; 
      srcBuf[(j * width + i) * nbands + 1] = (j) % 256; 
      srcBuf[(j * width + i) * nbands + 2] = (j + i) % 256; 
     } 
    } 

    int tj_stat = tjCompress2(handle, srcBuf, width, pitch, height, 
     pixelFormat, &(jpegBuf), &jpegSize, jpegSubsamp, jpegQual, flags); 
    if(tj_stat != 0) 
    { 
     const char *err = (const char *) tjGetErrorStr(); 
     cerr << "TurboJPEG Error: " << err << " UNABLE TO COMPRESS JPEG IMAGE\n"; 
     tjDestroy(handle); 
     handle = NULL; 
     return -1; 
    } 

    FILE *file = fopen("out.jpg", "wb"); 
    if (!file) { 
     cerr << "Could not open JPEG file: " << strerror(errno); 
     return -1; 
    } 
    if (fwrite(jpegBuf, jpegSize, 1, file) < 1) { 
     cerr << "Could not write JPEG file: " << strerror(errno); 
     return -1; 
    } 
    fclose(file); 

    //write out the compress date to the image file 
    //cleanup 
    int tjstat = tjDestroy(handle); //should deallocate data buffer 
    handle = 0; 
} 
संबंधित मुद्दे