Android NDK uses Libjpeg to parse JPEG images and display them on Surfaceview

Source: Internet
Author: User

Surfaceview is probably the most appealing component of Google's offer to developers, because Surfaceview interface refreshes allow updates in non-UI threads, because of this, many applications that frequently update the interface, such as video players, games, Animation effects are always developed based on Surfaceview and its subclasses.

One of the applications I've been working on recently is an application that handles images and displays images, which are memory killers, and the processing of images is very computationally significant, which is a headache.

Analyze the application and select the implementation technology

1, processing the image of large operations, in order to improve the efficiency of operation, choose to use C language processing pictures

2, the need for large memory space, in order to save memory and improve efficiency, need to read from the C language files, and early release


Below, write down the basic process of showing the picture

1, the user selects the picture

2. Get the path of the picture that the user chooses

3, call the method of displaying pictures (C method)


The first part: User select picture

Intent Intent = new Intent (intent.action_get_content);//Action_open_documentintent.addcategory (Intent.category_ openable); Intent.settype ("image/jpeg"); if (Android.os.Build.VERSION.SDK_INT >= Android.os.Build.VERSION_CODES. KITKAT) {Startactivityforresult (intent, Select_pic_kitkat);} else {Startactivityforresult (intent, select_pic);}


The second part gets the path of the picture that the user chooses

protected void Onactivityresult (int requestcode, int resultcode, Intent data) {if (ResultCode = = RESULT_OK) {if (Requestco De = = select_pic) {Uri Originaluri = Data.getdata (); String[] proj = {MediaStore.Images.Media.DATA};//seems to be the encapsulated interface of the Android multimedia database, specifically looking at the android document cursor cursor = Managedquery ( Originaluri, proj, NULL, null,null);//According to my own understanding this is the index value of the picture that gets the user's choice int column_index = Cursor.getcolumnindexorthrow ( MediaStore.Images.Media.DATA);//move the cursor to the beginning, this is very important, it is easy to cause the cross-border Cursor.movetofirst ();//finally get the picture path from the index value string path = Cursor.getstring (Column_index); LOG.V ("Picture path:", Path), if (Path.endswith (". jpg")) {Isonactivityresult = True;imgpath = Path;}}};

Part III: How to invoke a display image

This section needs to be noted, written in Surfaceholder's callback method, so that the surface of Surfaceview is successfully built, and then the surface is passed into C code for processing

<span style= "White-space:pre" ></span>svshow = (Surfaceview) Findviewbyid (R.id.svShow); SvHolder = Svshow.getholder (); Svholder.addcallback (new Surfaceholder.callback () {public void surfacechanged (Surfaceholder Holder, int format,int width, int height) {log.v (TAG, "surfacechanged format=" + Format + ", width=" + width + ", height=" + height);} public void surfacecreated (Surfaceholder holder) {LOG.V (TAG, "surfacecreated"); if (Isonactivityresult && Imgpath! = null) {showjpg (Holder.getsurface (), Imgpath);}} public void surfacedestroyed (Surfaceholder holder) {LOG.V (TAG, "surfacedestroyed");});


The code that actually handles the picture and displays the picture

Jniexport void Jnicall java_com_example_photoprocessing_activity_surfaceprocessingactivity_showjpg (JNIENV * env, Jobject activity, jobject surface, jstring img) {const char * imgchar;jboolean * Iscopy;imgchar = Env->getstringutfchar S (IMG, 0); Anativewindow_buffer Nwbuffer; Logi ("img Path:%s", Imgchar); Logi ("Anativewindow_fromsurface"); Anativewindow * Manativewindow = anativewindow_fromsurface (env, surface), if (Manativewindow = = NULL) {LOGE (" Anativewindow_fromsurface error "); return;} Logi ("Anativewindow_lock"), if (0! = Anativewindow_lock (Manativewindow, &nwbuffer, 0)) {LOGE ("Anativewindow_lock Error "); return;} Read_jpeg_file_show (Imgchar, Nwbuffer), if (Nwbuffer.format = = window_format_rgba_8888) {logi ("NwBuffer->format = = window_format_rgba_8888 ");} Logi ("Anativewindow_unlockandpost"), if (0! = Anativewindow_unlockandpost (Manativewindow)) {LOGE ("Anativewindow_ Unlockandpost error "); return;} Env->releasestringutfchars (Img,imgchar); Anativewindow_release (Manativewindow); Logi ("ANativewindow_release "); return;} 
int read_jpeg_file_show (const char *input_filename,anativewindow_buffer& nwbuffer) {struct JPEG_DECOMPRESS_ struct cinfo;struct jpeg_error_mgr jerr; FILE *input_file; Jsamparray buffer;int row_width;unsigned Char *buffertmp;cinfo.err = jpeg_std_error (&jerr); if (Input_file = fopen ( Input_filename, "RB")) = = NULL) {fprintf (stderr, "can ' t open%s\n", input_filename); Logi ("Can ' t open jpg1"); return-1;} Initialization information jpeg_create_decompress (&AMP;CINFO); Logi ("Initialization Information");/* Specify data source for decompression *///specify picture jpeg_stdio_src (&cinfo, input_file); Logi ("Specify Picture");/* Read file header, set default decompression parameters */(void) Jpeg_read_header (&cinfo, TRUE); Logi ("Read header information, set default decompression parameters");/* Start decompressor */(void) jpeg_start_decompress (&cinfo); Logi ("decompression"); row_width = Cinfo.output_width * cinfo.output_components; Logi ("width of picture:%d image of high%d color length:%d", Cinfo.output_width, Cinfo.output_height, cinfo.output_components); buffer = (* Cinfo.mem->alloc_sarray) ((j_common_ptr) &cinfo, jpool_image,row_width, 1);//Line buffertmp = (unsigned char *) malloc (row_width); memset (buffertmp, 0, Row_ width);  Logi ("malloc and Memset");//tmp = output_buffer;/* Process data */int get8h5 = 248, Get8h6 = 252;__uint16_t * Line = (__uint16_t *) nwbuffer.bits;int wheight = 0;int Scalew = 1, Scaleh = 1;if (Cinfo.output_width > Nwbuffer.width) {SC Alew = Cinfo.output_width/nwbuffer.width;} Logi ("scale of img =%d", scalew); for (int i = 0, choosehnum = 0; i < cinfo.output_height; i++) {//Get one row jpeg_read_scanl  Ines (&cinfo, buffer, 1); buffertmp = *buffer;//Select rows according to scale if (i% Scalew = 0 && choosehnum++ < nwbuffer.height) {//logi ("Nwbuffer->format = = window_format_rgb_565"); for (int j = 0, choosewnum = 0; J < Cinfo.output_width; J + +) { if (j% Scalew = = 0) {if (Nwbuffer.format = = window_format_rgb_565) {Line[choosewnum] = ((__uint16_t) buffertmp[3 * j + 0 ]& get8h5) << 8| ((__uint16_t) (buffertmp[3 * j + 1] & Get8h6) << 3) | ((__uint16_t) (Buffertmp[3 * j + 2] & Get8h6) >> 3); choosewnum++;}}} Line = line + nwbuffer.stride;}} memcpy (TMP, *buffer, row_width);/tmp + = Row_width; (void) jpeg_finish_decompress (&ci NFO); Logi ("Jpeg_finish_decompress!"); Jpeg_destroy_decompress (&cinfo); Logi ("Jpeg_destroy_decompress!"); * Close files, if we opened them */fclose (input_file); return 0;}

Demo Show:

Click Show image to start selecting a picture:



After the selection is finished, it automatically displays:






Android NDK uses Libjpeg to parse JPEG images and display them on Surfaceview

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.