' $ Chop out the used area and expand height to 133% for 16x9 conversion (this version maintains crop box centre position) ' 'The project.xml will have already been parsed to add cr/lf, and both it + all the .jpg's will be in /PhotoStory sub-folder ' IF you get 'OUT OF STRING SPACE' when you launch the script, go back and and add the cr/lf :-) ' ' REMEMBER ... ' Direction X is wd (width), Y is ht (height). Do the X, wd first .. because the ht will be 133% distorted ' The 'bounding box' makes things confusing - so dump it at the start and re-calc at the end ' We are using 'signed' 16bit numbers. This means that no pixel height count can exceed 32k/4 = 8k (or we get overflow during 4/3 calcs) ' s = crop start, e = crop end, i = input image, u = used image, o = output image, b = bounding box ' (so sX = start width offset, swd = start width etc) ' ' subroutines to add extra used height or width pixels DECLARE SUB addHeight (uwd%, uht%, uX%, uY%, iwd%, iht%) DECLARE SUB addWidth (uwd%, uht%, uX%, uY%, iwd%, iht%) ' subroutine to do the spread DECLARE SUB spreadPix (exPix%, used%, uoff%, img%) ' subroutine to redo the bounding box DECLARE SUB newBbox (bwd%, bht%, owd%, oht%) ' subroutine to put drop box into image area DECLARE SUB cropInimg (cX%, cY%, cW%, cH%, iW%, iH%) DECLARE SUB get2vals (in$, middl$, end$, dmy1$, frwd%, dmy2$, frht%) ' ver$ = "This version CHOP133E" ' CLEAR ' ' can't use the double-quote symbol (") in a line of qbasic code, so assign it to a variable in case we need it q$ = CHR$(34) ' OPEN "C:\QBASIC\PSTORY3\Project.xml" FOR INPUT AS #1 OPEN "C:\QBASIC\PSTORY3\x133.xml" FOR OUTPUT AS #2 OPEN "C:\QBASIC\PSTORY3\CHOP_133.LOG" FOR OUTPUT AS #4 PRINT ver$ PRINT #4, ver$ ' DO LINE INPUT #1, in$ ' find the next image Qpos = INSTR(in$, " 1 THEN GOTO skip1 ' OK, got we have an image def. start by saving the first line PRINT #4, PRINT #4, "Found Vu "; OPEN "C:\QBASIC\PSTORY3\vu.tmp" FOR OUTPUT AS #3 PRINT #3, in$ ' extract the jpg name it's from first double quotes to second Q1pos = INSTR(in$, q$) Q2pos = INSTR(Q1pos + 1, in$, q$) iname$ = MID$(in$, Q1pos + 1, Q2pos - Q1pos - 1) ' say we have the image name PRINT "processing "; iname$ PRINT #4, iname$ 'extract the input width and height, breaking the line into 3 parts CALL get2vals(in$, middl$, end$, "width=", iwd%, "height=", iht%) PRINT #4, "Initial Image size iwd x iht :", iwd%; " x "; iht% ' skip to the bounding box (it's the line starting 1 THEN GOTO skip2 ' extract the values CALL get2vals(in$, middl$, end$, "Width=", bwd%, "Height=", bht%) PRINT #4, "Initial Bounding box bwd x bht :", bwd%; " x "; bht% ' ' calc the existing crop box offset width and height adjusts (one will be 0) cXwdOff% = (bwd% - iwd%) / 2 cYhtOff% = (bht% - iht%) / 2 ' get & save the start crop box settings LINE INPUT #1, in$ PRINT #3, in$ ' extract the Start crop X & Y offset (the Start size) values in two steps CALL get2vals(in$, middl$, end$, "LeftX=", sX%, "LeftY=", sY%) ' adjust for bounding box sX% = sX% - cXwdOff% sY% = sY% - cYhtOff% PRINT #4, "Start crop offset (image relative)", sX%; " x "; sY% ' extract the start crop sizes, wd & ht in$ = end$ CALL get2vals(in$, middl$, end$, "width=", swd%, "height=", sht%) ' ' get & save the End crop box settings LINE INPUT #1, in$ PRINT #3, in$ ' extract the End crop offset and End size values in two steps CALL get2vals(in$, middl$, end$, "LeftX=", eX%, "LeftY=", eY%) ' adjust for bounding box eX% = eX% - cXwdOff% eY% = eY% - cYhtOff% PRINT #4, "End crop offset (image relative)", eX%; " x "; eY% ' extract the end crop sizs wd & ht in$ = end$ CALL get2vals(in$, middl$, end$, "width=", ewd%, "height=", eht%) ' 'OK, we can now start doing the calculations ' both crop boxes must be within the real image area - if not, then adjust them now ' CALL cropInimg(sX%, sY%, swd%, sht%, iwd%, iht%) PRINT #4, "Mod Start crop box offset X x Y is ", sX%; " x "; sY% PRINT #4, "Mod Start crop box size wd x ht is ", swd%; " x "; sht% ' CALL cropInimg(eX%, eY%, ewd%, eht%, iwd%, iht%) PRINT #4, "Mod End crop box offset X x Y is ", eX%; " x "; eY% PRINT #4, "Mod End crop box size wd x ht is ", ewd%; " x "; eht% ' ' OK now calc the used image area start offset (it's lower of the 2 crop box starts) uX% = sX% IF eX% < uX% THEN uX% = eX% uY% = sY% IF eY% < uY% THEN uY% = eY% PRINT #4, "Initial offset to used image area :", uX%; " x "; uY% ' ' how much image will we use ? ' first find the end of the cropped area & calc used width uwd% x used height uht% ' (it's max of the 2 crop box ends) & then adjust for start offset uwd% = eX% + ewd% IF sX% + swd% > uwd% THEN uwd% = sX% + swd% ' remove offset from used width uwd% = uwd% - uX% ' uht% = eY% + eht% IF sY% + sht% > uht% THEN uht% = sY% + sht% ' remove offset uht% = uht% - uY% ' OK we have the used image offsets and size - but it may not generate 4:3 output ' (note - the crop box offsets are still pointing at the original locations) ' dont forget the 133% distort, so compare 3 wd with 4/3 * 4 ht for output aspect ratio ' to avid overflow, compare wd with 16/9 height IF uwd% > (16 / 9) * uht% THEN CALL addHeight(uwd%, uht%, uX%, uY%, iwd%, iht%) ELSE IF uwd% < (16 / 9) * uht% THEN CALL addWidth(uwd%, uht%, uX%, uY%, iwd%, iht%) ' OK on return we have the final used X Y offsets and wd ht PRINT #4, "Used image area final offset:", uX%; " x "; uY% PRINT #4, "Used image area final size:", uwd%; " x "; uht% ' adjust the crop boxes sX% = sX% - uX% sY% = sY% - uY% eX% = eX% - uX% eY% = eY% - uY% PRINT #4, "Adjusted Start crop box offset :", sX%; " x "; sY% PRINT #4, "Adjusted End crop box offset :", eX%; " x "; eY% ' ' OK ready to do the main calc .. what's the basic zoom factor ? ozoom! = 1! ' what zoom do we need to get at least 2880 pixels in the smallest crop box width ? IF 2880 / swd% > ozoom! THEN ozoom! = 2880 / swd% IF 2880 / ewd% > ozoom! THEN ozoom! = 2880 / ewd% ' ' not allowed to zoom beyond 7000 pixels wd x ht ' check what output width this gives us and adjust down if > 7200 owd% = uwd% * ozoom! IF owd% > 7200 THEN ozoom! = 7200 / uwd% ' now check the 133% output height and adjust down again if necessary oht% = 4 * uht% * ozoom! / 3 IF oht% > 7200 THEN ozoom! = (5250 / uht%) ' ' OK that's the final zoom calculated - PRINT "x "; ozoom! PRINT #4, "Final Zoom is ", , ozoom! ' ' calc all the output sizes based on the final zoom owd% = uwd% * ozoom! ' calc oht with 133% (4/3rds) extra zoom oht% = (4 * uht% * ozoom!) / 3 PRINT #4, "Final image width x height will be :", owd%; "x"; oht% ' ' calc the output crop box sizes (they must be 4x3, but based on wd due to o/p 133% ht adjust) swd% = swd% * ozoom! sht% = (3 * swd%) / 4 PRINT #4, "Final start crop box size wd x ht :", swd%; " x "; sht% ewd% = ewd% * ozoom! eht% = (3 * ewd%) / 4 PRINT #4, "Final end crop box size wd x ht :", ewd%; " x "; eht% ' ' redo the Bounding box CALL newBbox(bwd%, bht%, owd%, oht%) PRINT #4, "Final Bounding box is ", , bwd%; "x"; bht% ' ' calc the new crop box offsets based on final zoom ' calc bounding box offset xOff% = (bwd% - owd%) / 2 yOff% = (bht% - oht%) / 2 ' adjust width for zoom and bounding box sX% = (sX% * ozoom!) + xOff% ' adjust height for zoom, half of 133% (11.6% = 7/6) and bounding box sY% = 7 * sY% * ozoom! / 6 sY% = sY% + yOff% ' eX% = (eX% * ozoom!) + xOff% eY% = 7 * eY% * ozoom! / 6 eY% = eY% + yOff% ' cropbox and 133% height adjust ' ' make sure crop is inside the bounding box ' re-use the cropInimg subrouting using bbox instead of image CALL cropInimg(sX%, sY%, swd%, sht%, bwd%, bht%) CALL cropInimg(eX%, eY%, ewd%, eht%, bwd%, bht%) ' PRINT #4, "Final start crop offset wd x ht :", sX%; " x "; sY% PRINT #4, "Final end crop offset wd x ht :", eX%; " x "; eY% ' ' OK, all calcs done = we can go modify the Visual Unit params ' ============================================================ ' ' Skip forward to the 4 1 THEN GOTO skip5 ' Mod. the Relative (to bounding box) settings ' chop the start, mid and end$ for the left & top entries ' Note iwd and iht are dummy - we don't need the existing values CALL get2vals(in$, middl$, end$, "left=", iwd%, "top=", iht%) ' calc the start crop offset (relative to bounding box) rleft# = sX% / bwd% IF rleft# = 0! THEN rleft$ = "0" ELSE rleft$ = "0" + LTRIM$(STR$(rleft#)) rtop# = sY% / bht% IF rtop# = 0! THEN rtop$ = "0" ELSE rtop$ = "0" + LTRIM$(STR$(rtop#)) rel$ = in$ + rleft$ + middl$ + rtop$ ' OK now get the second two values out of the rest of the string in$ = end$ CALL get2vals(in$, middl$, end$, "width=", iwd%, "height=", iht%) rwd# = swd% / bwd% IF rwd# = 1! THEN rwd$ = "1" ELSE rwd$ = "0" + LTRIM$(STR$(rwd#)) rht# = sht% / bht% IF rht# = 1! THEN rht$ = "1" ELSE rht$ = "0" + LTRIM$(STR$(rht#)) in$ = rel$ + in$ + rwd$ + middl$ + rht$ + end$ ' PRINT #3, in$ ' LINE INPUT #1, in$ CALL get2vals(in$, middl$, end$, "left=", iwd%, "top=", iht%) rleft# = eX% / bwd% IF rleft# = 0! THEN rleft$ = "0" ELSE rleft$ = "0" + LTRIM$(STR$(rleft#)) rtop# = eY% / bht% IF rtop# = 0! THEN rtop$ = "0" ELSE rtop$ = "0" + LTRIM$(STR$(rtop#)) rel$ = in$ + rleft$ + middl$ + rtop$ in$ = end$ CALL get2vals(in$, middl$, end$, "width=", iwd%, "height=", iht%) rwd# = ewd% / bwd% IF rwd# = 1! THEN rwd$ = "1" ELSE rwd$ = "0" + LTRIM$(STR$(rwd#)) rht# = eht% / bht% IF rht# = 1! THEN rht$ = "1" ELSE rht$ = "0" + LTRIM$(STR$(rht#)) in$ = rel$ + in$ + rwd$ + middl$ + rht$ + end$ ' PRINT #3, in$ ' ' OK, done ' ' Close temp & reopen CLOSE 3 OPEN "C:\QBASIC\PSTORY3\vu.tmp" FOR INPUT AS #3 ' get the first line (it's the image data) LINE INPUT #3, in$ ' ' now sort out the 1 THEN GOTO skip3 ' ' break it up CALL get2vals(in$, middl$, end$, "Width=", iwd%, "Height=", iht%) ' recombine with new values in$ = in$ + LTRIM$(STR$(bwd%)) + middl$ + LTRIM$(STR$(bht%)) + end$ ' and save the bounding box parameter string PRINT #2, in$ ' ' OK the two iW% THEN cX% = iW% - cW% IF cX% < 0 THEN cX% = 0 IF cW% > iW% THEN cW% = iW% Ht% = (3 * cW%) / 4 ' If we reduced the height, adjust the Y offset IF cH% < Ht% THEN cY% = cY% + ((cH% - Ht%) / 2) ' check it's still within the image area & reduce offset as needed IF (cY% + Ht%) > iH% THEN cY% = iH% - Ht% IF cY% < 0 THEN cY% = 0 cH% = Ht% IF Ht% > iH% THEN cH% = iH% ' reset the width cW% = (4 * cH%) / 3 END SUB ' subroutine to extract 2 values and break the line into 3 parts (b4 first val, middle, after 2nd val) SUB get2vals (in$, middl$, end$, v1$, v1%, v2$, v2%) q$ = CHR$(34) ' locate start of the first value (don't forget to allow +1 to skip the leading double quote) pos1 = INSTR(in$, v1$) + LEN(v1$) + 1 ' locate the end of v1 pos1e = INSTR(pos1 + 1, in$, q$) ' set value 1 v1% = VAL(MID$(in$, pos1, pos1e - pos1)) ' ' locate start of second value (don't forget to allow for the leading double quote) pos2 = INSTR(in$, v2$) + LEN(v2$) + 1 ' locate the end of v2 pos2e = INSTR(pos2 + 1, in$, q$) ' set value 2 v2% = VAL(MID$(in$, pos2, pos2e - pos2)) ' ' now split off the end and the middle (keeping the double quotes) end$ = MID$(in$, pos2e) middl$ = MID$(in$, pos1e, pos2 - pos1e) in$ = LEFT$(in$, pos1 - 1) END SUB ' subroutine to redo the bounding box SUB newBbox (bwd%, bht%, owd%, oht%) bwd% = owd% bht% = oht% ' one of these may be too low for a 4:3 aspect ratio IF (3 * bwd%) < (4 * oht%) THEN bwd% = (4 * oht%) / 3 ELSE IF (4 * bht%) < (3 * owd%) THEN bht% = (3 * owd%) / 4 END SUB ' subroutine to do the spread SUB spreadPix (exPix%, used%, uoff%, img%) ' try to spread them evenly between Y offsets and image ht exHalf% = exPix% / 2 exPix% = exPix% - exHalf% ' subtract from offset IF uoff% > 0 THEN IF uoff% > exHalf% THEN uoff% = uoff% - exHalf% exHalf% = 0 ELSE exHalf% = exHalf% - uoff% uoff% = 0 END IF END IF ' OK add back any we didnt manage to subtract exPix% = exPix% + exHalf% ' can we add input pixels IF img% - used% > exPix% THEN used% = used% + exPix% exPix% = 0 ELSE exPix% = exPix% - (img% - used%) used% = img% END IF ' subtract any left over from offset IF uoff% > exPix% THEN uoff% = uoff% - exPix% exPix% = 0 ELSE exPix% = exPix% - uoff% uoff% = 0 END IF END SUB