;+----------------------------------------------------------------- ;+ ; NAME: ; WRITE_MPEG ; ; PURPOSE: ; Write a sequence of images as an mpeg movie ; ; CATEGORY: ; animation ; ; CALLING SEQUENCE: ; WRITE_MPEG,'movie.mpg',ims ; ; INPUTS: ; ims: sequence of images as a 3D array with dimensions [sx, sy, nims] ; where sx = xsize of images ; sy = ysize of images ; nims = number of images ; ; OPTIONAL INPUTS: ; ; KEYWORD PARAMETERS: ; delaft: if set delete temporary array after movie was created ; you should actually always do it otherwise you get ; problems with permissions on multiuser machines (since ; /tmp normally has the sticky bit set) ; rep: if given means repeat every image 'rep' times ; (as a workaround to modify replay speed) ; ; OUTPUTS: None ; OPTIONAL OUTPUTS: ; ; COMMON BLOCKS: ; ; SIDE EFFECTS: ; creates some files in TMPDIR which are only removed when ; the DELAFT keyword is used ; ; RESTRICTIONS: ; depends on the program mpeg_encode from University of ; California, Berkeley, which must be installed in /usr/local/bin ; ; PROCEDURE: ; writes a parameter file based on the dimensions of the image ; array + the sequence of images in ppm format into a ; temporary directory; finally spawns mpeg_encode to build the ; movie ; ; EXAMPLE: ; IDL> s=openmdsshot('efit',112800) ; IDL> data3d=mdsvalue('\efit01::psirz') ; IDL> write_mpeg, 'efit_112800.mpg', bytscl(congrid(data3d,65*8,65*8,128)) ; or ; IDL>write_mpeg,'test.mpg',reform([[dist(100)],[dist(100)],[dist(100)]],100,100,3) ; ; MODIFICATION HISTORY: ; 15-Jul-04 warn if file not 3d [BD] ; Mon Nov 18 13:13:53 1996, Christian Soeller ; ; ; grabbed original from the net and made slight modifications ;------------------------------------------------------------- FUNCTION pseudo_to_true, image8 s = SIZE(image8) IF s(0) NE 2 THEN BEGIN MESSAGE, 'input array must be 2D BYTE array.' RETURN, -1 ENDIF width = s(1) height = s(2) ; Load current color table into byte arrays TVLCT, red, green, blue, /GET image24 = BYTARR(3,width, height) image24(0,*,*) = red(image8(*,*)) image24(1,*,*) = green(image8(*,*)) image24(2,*,*) = blue(image8(*,*)) RETURN, image24 END ;------------------------------------------------------------- PRO WRITE_MPEG, mpegFileName, image_array, delaft=delaft, $ rep=rep, magnification=magnification if !VERSION.OS EQ "vms" then begin beep print, ' This only works on Solaris Unix' return endif if n_elements(rep) eq 0 then rep=1 movieSize = SIZE(image_array) if movieSize[0] ne 3 then begin print, ' second input to WRITE_MPEG must be a 3-D array' return endif xSize = movieSize(1) ySize = movieSize(2) nFrames = movieSize(3)*rep spawn,'which mpeg_encode', result if nwords( result ) ne 1 then begin beep print, ' ' print, ' mpeg_encode must be in your path' print, ' ' if !VERSION.OS EQ "linux" then begin print, ' If you are running at PPPL, try a Solaris machine' print, ' ' endif return endif nDigits = 1+FIX(ALOG10(nFrames)) formatString = STRCOMPRESS('(i'+STRING(nDigits)+'.'+STRING(nDigits)$ + ')', /REMOVE_ALL) ON_IOERROR, badWrite ; Make a temporary directory if necessary or clear it otherwise' TMPDIR = '/tmp/idl2mpeg.frames' SPAWN, 'if test -d ' + TMPDIR + '; then echo "exists"; fi', result, /SH dirExists = result(0) EQ 'exists' IF dirExists THEN command = '/bin/rm ' + TMPDIR + '/*' $ ELSE command = 'mkdir ' + TMPDIR SPAWN, command ; Write each frame into TMPDIR as a 24-bit .ppm image file framenum=0 FOR ino = 0, movieSize(3)-1 DO BEGIN frame = image_array(*,*,ino) if keyword_set( magnification ) then $ frame = rebin( frame, xSize*magnification, $ ySize*magnification ) image = pseudo_to_true( frame ) for j=0,rep-1 do begin fileName = TMPDIR + '/frame.' + STRING(frameNum,FORMAT=formatString)$ + '.ppm' WRITE_PPM, fileName, image PRINT, 'Wrote temporary PPM file for frame ', frameNum+1 framenum=framenum+1 endfor ENDFOR ; Build the mpeg parameter file paramFile = TMPDIR + '/idl2mpeg.params' OPENW, unit, paramFile, /GET_LUN PRINTF, unit, 'PATTERN IBBBBBBBBBBP' PRINTF, unit, 'OUTPUT ' + mpegFileName PRINTF, unit, 'GOP_SIZE 16' PRINTF, unit, 'SLICES_PER_FRAME 5' PRINTF, unit, 'BASE_FILE_FORMAT PNM' PRINTF, unit, 'INPUT_CONVERT *' PRINTF, unit, 'INPUT_DIR /tmp/idl2mpeg.frames' PRINTF, unit, 'INPUT' PRINTF, unit, 'frame.*.ppm ['+string(FORMAT=formatString,0) + $ '-' + string(FORMAT=formatString,nFrames-1) + ']' PRINTF, unit, 'END_INPUT' PRINTF, unit, 'PIXEL FULL' PRINTF, unit, 'RANGE 5' PRINTF, unit, 'PSEARCH_ALG LOGARITHMIC' PRINTF, unit, 'BSEARCH_ALG SIMPLE' PRINTF, unit, 'IQSCALE 6' PRINTF, unit, 'PQSCALE 6' PRINTF, unit, 'BQSCALE 6' PRINTF, unit, 'REFERENCE_FRAME ORIGINAL' PRINTF, unit, 'FORCE_ENCODE_LAST_FRAME' FREE_LUN, unit ; spawn a shell to process the mpeg_encode command SPAWN, result + ' ' + paramFile IF KEYWORD_SET(delaft) then $ SPAWN, 'rm -r ' + TMPDIR RETURN badWrite: alert, 'Unable to write MPEG file!' END