1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934 |
- <template>
- <div>
- <el-container style="user-select: none; height: 100vh;">
- <el-container>
- <!-- #333744 -->
- <el-aside width="170px" style="border-right: 1px solid #fafafa; background-color: #333744;">
- <p class="soft-name" style="-webkit-app-region: drag; color: #fff;">
- <img src="../assets/image/icon.png" class="soft-icon" />
- {{productName}}
- </p>
- <el-menu default-active="1" class="xy-menu" active-text-color="#409EFF" background-color="#333744" text-color="#fff" style="margin-top: 10px;">
- <el-menu-item index="1" @click="setMenuIndex(1)">
- <img src="../assets/image/m-geshi.png" class="m-image"/>
- <span slot="title">格式转换</span>
- </el-menu-item>
- <el-menu-item index="2" @click="setMenuIndex(2)">
- <img src="../assets/image/m-yasuo.png" class="m-image"/>
- <span slot="title">图片压缩</span>
- </el-menu-item>
- <el-menu-item index="11" @click="setMenuIndex(11)">
- <img src="../assets/image/m-dpi.png" class="m-image"/>
- <span slot="title">修改DPI</span>
- </el-menu-item>
- <el-menu-item index="3" @click="setMenuIndex(3)">
- <img src="../assets/image/m-chicun.png" class="m-image"/>
- <span slot="title">更改尺寸</span>
- </el-menu-item>
- <el-menu-item index="4" @click="setMenuIndex(4)">
- <img src="../assets/image/m-meihua.png" class="m-image"/>
- <span slot="title">美化图片</span>
- </el-menu-item>
- <el-menu-item index="5" @click="setMenuIndex(5)">
- <img src="../assets/image/m-shuiyin.png" class="m-image"/>
- <span slot="title">添加水印</span>
- </el-menu-item>
- <el-menu-item index="6" @click="setMenuIndex(6)">
- <img src="../assets/image/m-yuanjiao.png" class="m-image"/>
- <span slot="title">图片圆角</span>
- </el-menu-item>
- <el-menu-item index="9" @click="setMenuIndex(9)">
- <img src="../assets/image/m-xuanzhuan.png" class="m-image"/>
- <span slot="title">批量旋转</span>
- </el-menu-item>
- <el-menu-item index="7" @click="setMenuIndex(7)">
- <img src="../assets/image/m-name.png" class="m-image"/>
- <span slot="title">批量命名</span>
- </el-menu-item>
- <el-menu-item index="10" @click="setMenuIndex(10)">
- <img src="../assets/image/m-caijian.png" class="m-image"/>
- <span slot="title">批量裁剪</span>
- </el-menu-item>
- <el-menu-item index="8" @click="setMenuIndex(8)">
- <img src="../assets/image/m-pinjie.png" class="m-image"/>
- <span slot="title">图片拼接</span>
- </el-menu-item>
- </el-menu>
- </el-aside>
- <el-container>
- <el-header height="45px" style="background-color: #fafafa; padding: 0 10px;">
- <soft-header ref="headerRef" @update-soft="updateSoft()"
- @export-file="exportImg"></soft-header>
- </el-header>
- <el-main ref="el-main" style="background-color: #fafafa;">
- <template>
- <div class="content-top">
- <div>
- <el-button type="primary" size="small" icon="el-icon-document"
- @click="pickFile()">添加文件</el-button>
- <el-button type="primary" size="small" icon="el-icon-folder"
- @click="pickDir()">添加文件夹</el-button>
- <el-button type="info" size="small" icon="el-icon-delete"
- @click="clearList()">清空图片</el-button>
- </div>
- </div>
-
- <div v-if="(imgList.length == 0 && menuIndex != 8 && menuIndex != 10) || (mergeList.length == 0 && menuIndex == 8) || (cropList.length == 0 && menuIndex == 10)" class="upload-area">
- <div class="file-area" @click="pickFile()" id="drag-jimp">
- <div>
- <img src="../assets/image/upload.png" style="width: 220px;"/>
- <p style="font-size: 16px;">将图片文件拖住至此处,或点击此处选择图片</p>
- </div>
- </div>
- </div>
-
- <div class="img-content" v-else>
- <!-- 1、格式转换 2、图片压缩 3、修改dpi-->
- <template v-if="menuIndex == 1 || menuIndex == 2 || menuIndex == 11 || menuIndex == 7">
- <div :style="menuIndex == 7 ? 'height: calc(100% - 120px);' : 'height: calc(100% - 78px);'">
- <vxe-table ref="xRenameTable" v-show="menuIndex == 7" show-overflow class="img-table" max-height="100%" empty-text="没有更多数据了!" :row-config="{isCurrent: true, isHover: true}"
- :edit-config="{trigger: 'click', mode: 'cell'}" :data="imgList" :scroll-y="{enabled: true}">
- <vxe-column field="name" :title="'文件名'+'(' + imgList.length + ')'" min-width="120"></vxe-column>
- <vxe-column field="newName" title="新文件名" min-width="120"></vxe-column>
- <vxe-column field="path" title="文件位置" min-width="200"></vxe-column>
- <vxe-column field="status" title="状态" min-width="110" max-width="160">
- <template #default="{ row }">
- <div v-if="row.status == '2'"><i class="el-icon-circle-check" style="color: #19be6b;"></i> 修改成功</div>
- <div v-else-if="row.status == '3'"><i class="el-icon-circle-close" style="color: #ed4014;"></i> 修改失败</div>
- <div v-else-if="row.status == '4'"><i class="el-icon-warning-outline" style="color: #ff9900;"></i> 文件被修改</div>
- <div v-else-if="row.status == '5'"><i class="el-icon-warning-outline" style="color: #ff9900;"></i> 文件已存在</div>
- <div v-else>待操作</div>
- </template>
- </vxe-column>
- <vxe-column field="action" title="操作" width="80">
- <template #default="{ row, rowIndex }">
- <i class="el-icon-delete cur-pointer" @click="delImgFile(rowIndex)"></i>
- </template>
- </vxe-column>
- </vxe-table>
-
- <vxe-table ref="xTable" v-show="menuIndex != 7" show-overflow class="img-table" max-height="100%" empty-text="没有更多数据了!" :row-config="{isCurrent: true, isHover: true}"
- :edit-config="{trigger: 'click', mode: 'cell'}" :data="imgList" :scroll-y="{enabled: true}">
- <vxe-column field="name" :title="'文件名'+'(' + imgList.length + ')'" min-width="120"></vxe-column>
- <!-- <vxe-column field="path" title="缩略图" width="70">
- <template #default="{ row }">
- <el-image style="width: 30px; height: 30px" :src="row.path" fit="contain"></el-image>
- </template>
- </vxe-column> -->
- <vxe-column field="size" title="大小" min-width="100" max-width="120">
- <template #default="{ row }">
- <span v-if="row.width == 0 && row.height == 0">-</span>
- <span v-else>{{row.size}}</span>
- </template>
- </vxe-column>
-
- <vxe-column field="width" title="尺寸" min-width="110" max-width="130">
- <template #default="{ row }">
- <span v-if="row.width == 0 && row.height == 0">{{'加载中 '+row.loadPercent+'%'}}</span>
- <span v-else>{{row.width + '*' + row.height}}</span>
- </template>
- </vxe-column>
- <vxe-column field="progress" title="进度" min-width="110" max-width="160">
- <template #default="{ row }">
- <el-progress :text-inside="true" :stroke-width="20" :percentage="row.percent"></el-progress>
- </template>
- </vxe-column>
- <vxe-column field="action" title="操作" width="80">
- <template #default="{ row, rowIndex }">
- <i class="el-icon-delete cur-pointer" @click="delImgFile(rowIndex)"></i>
- </template>
- </vxe-column>
- </vxe-table>
- </div>
- </template>
-
-
- <!-- 3、更改尺寸 4、美化图片 5、添加水印 6、图片圆角 9、批量旋转 10、图片裁剪 -->
- <template v-else-if="[3,4,5,6,9,10].indexOf(menuIndex) > -1">
- <div class="soft-content">
- <div class="content-left" style="width: calc(100% - 270px)">
- <!-- 图片裁剪 -->
- <div class="merge-flex">
- <div class="merge-scroll">
- <vxe-table fit v-if="menuIndex == 10" show-overflow :show-header="false" align="center" height="100%" :row-config="{isCurrent: true, isHover: true, height: 100}"
- :data="cropList" @cell-click="selectTabCrop">
- <vxe-column field="name" width="123" show-overflow>
- <template #default="{ row, rowIndex }">
- <vxe-button type="text" icon="vxe-icon-close" class="vxebtn-del" @click="deleteMerge(rowIndex, 'crop')"></vxe-button>
- <el-image style="width: 60px; height: 60px" :src="row.path" fit="contain" :title="row.name"></el-image>
- <div class="img-mid-progress" v-if="row.percent > 0">
- <el-progress :percentage="row.percent"></el-progress>
- </div>
- <div style="padding: 0 5px; overflow: hidden;white-space: nowrap;text-overflow: ellipsis;" :title="row.name">{{row.name}}</div>
- </template>
- </vxe-column>
- </vxe-table>
- <vxe-table fit v-else show-overflow :show-header="false" align="center" height="100%" :row-config="{isCurrent: true, isHover: true, height: 100}"
- :data="imgList" @cell-click="selectTab">
- <vxe-column field="name" width="123" show-overflow>
- <template #default="{ row, rowIndex }">
- <vxe-button type="text" icon="vxe-icon-close" class="vxebtn-del" @click="delImgFile(rowIndex)"></vxe-button>
- <el-image style="width: 60px; height: 60px" :src="row.path" fit="contain" :title="row.name"></el-image>
- <div class="img-mid-progress" v-if="row.percent > 0">
- <el-progress :percentage="row.percent"></el-progress>
- </div>
- <div style="padding: 0 5px; overflow: hidden;white-space: nowrap;text-overflow: ellipsis;" :title="row.name">{{row.name}}</div>
- </template>
- </vxe-column>
- </vxe-table>
- </div>
- <div class="merge-content" v-if="menuIndex == 10">
- <div v-if="cropOptionsImgInfo.width" style="text-align: right; color: #999; margin-bottom: 10px;">
- 原图尺寸{{cropOptionsImgInfo.width}}*{{cropOptionsImgInfo.height}}
- <span style="margin-left: 30px;">缩放比例{{cropOptions.cropScale.toFixed(1)}}%</span>
- <el-button style="margin-left: 30px;" type="primary" plain @click="previewImg" icon="el-icon-view">预览</el-button>
- </div>
-
- <div class="mlist-scroll" style="height: calc(100% - 50px);">
- <div style="width: 100%; height: 100%;">
- <vueCropper
- ref="cropper"
- :img="cropOptions.img"
- :autoCrop="cropOptions.autoCrop"
- :autoCropWidth="cropOptions.autoCropWidth"
- :autoCropHeight="cropOptions.autoCropHeight"
- :centerBox="cropOptions.centerBox"
- :fixed="cropOptions.fixed"
- :fixedNumber="cropOptions.fixedNumber"
- :maxImgSize="cropOptions.maxImgSize"
- :original="cropOptions.original"
- :canMove="cropOptions.canMove"
- :infoTrue="cropOptions.infoTrue"
- :info="true"
- :full="true"
- @realTime="realTime"
- @imgLoad="cropImgLoad"
- ></vueCropper>
- </div>
- </div>
- </div>
- <div class="merge-content" v-else>
- <div style="width: 100%; height: 100%;">
- <div id="show-img" class="show-img" style="position:relative;overflow: hidden; width: 100%; height: 100%;">
- <div style="position: absolute;top: 5px; left: 5px;padding: 0 10px 10px 10px; background: #00000060; color: #fff;font-size: 12px;z-index: 2;">
- <label>放大:</label>
- <el-slider v-model="viewScale" class="info-input" :min="0.5" :max="5" :step="0.1"></el-slider>
- {{viewScale.toFixed(1)}}
- </div>
- <img draggable="false" class="result-img" :src="imgSrc"
- :style="{borderRadius: menuIndex == 6 ? handleData.circularValue+'%' : 0, maxWidth: '80%',maxHeight: '500px', transform: 'rotate('+handleData.rotateValue+'deg) rotateY('+ (handleData.hflip ? '180' : '0') +'deg) rotateX('+ (handleData.vflip ? '180' : '0') +'deg) scale('+viewScale+')'}" />
- </div>
- </div>
- </div>
- </div>
- </div>
- <div class="content-right" style="width: 260px;">
- <div class="setting-area">
- <div class="img-handle">
- <!-- 3更改尺寸 -->
- <div v-if="menuIndex == 3">
- <div class="handle-item">
- <el-radio-group v-model="handleData.sizeType">
- <el-radio-button label="1">按比例调整</el-radio-button>
- <el-radio-button label="2">按尺寸调整</el-radio-button>
- </el-radio-group>
- </div>
- <div class="handle-item" v-if="handleData.sizeType == '1'">
- <label class="handle-label">缩放比例:</label>
- <el-input-number size="small" v-model="handleData.scaling" :min="1" :max="500"></el-input-number>
- </div>
- <div class="handle-item" v-if="handleData.sizeType == '2'">
- <label class="handle-label">宽度:</label>
- <el-input-number size="small" v-model="handleData.width" :min="1" @change="scaleWidthChange"></el-input-number> px
- </div>
- <div class="handle-item" v-if="handleData.sizeType == '2'">
- <label class="handle-label">高度:</label>
- <el-input-number size="small" v-model="handleData.height" :min="1" @change="scaleHeightChange"></el-input-number> px
- </div>
- <div class="handle-item" v-if="handleData.sizeType == '2'">
- <label class="handle-label">锁定比例:</label>
- <el-checkbox size="small" v-model="handleData.lockScale"></el-checkbox>
- <span style="font-size: 12px; color: #666;">(原始尺寸{{imgInfo.originalWidth}}:{{imgInfo.originalHeight}})</span>
- </div>
- </div>
- <!-- 4美化图片 -->
- <div v-if="menuIndex == 4">
- <div class="handle-item">
- <label class="handle-label">滤镜:</label>
- <el-select size="small" v-model="handleData.color" style="width:100px;" @change="handleImg">
- <el-option value="0" label="原图"></el-option>
- <el-option value="1" label="黑白"></el-option>
- <el-option value="2" label="灰度"></el-option>
- <el-option value="3" label="反转"></el-option>
- <!-- <el-option value="4" label="油画"></el-option> -->
- </el-select>
- </div>
- <!-- <div class="handle-item">
- <label class="handle-label">油画半径:</label>
- <el-slider v-model="handleData.paintValue" class="info-input" @change="handleImg" :min="1" :max="100"></el-slider>
- {{handleData.paintValue}}
- </div> -->
- <div class="handle-item">
- <label class="handle-label">色彩数:</label>
- <el-slider v-model="handleData.colorValue" class="info-input" @change="handleImg" :min="1" :max="256"></el-slider>
- {{handleData.colorValue}}
- </div>
- <div class="handle-item">
- <label class="handle-label">对比度:</label>
- <el-slider v-model="handleData.contrastValue" class="info-input" @change="handleImg" :min="-100" :max="100"></el-slider>
- {{handleData.contrastValue}}
- </div>
- <div class="handle-item">
- <label class="handle-label">亮度:</label>
- <el-slider v-model="handleData.brightnessValue" class="info-input" :min="-100" :max="100" @change="handleImg"></el-slider>
- {{handleData.brightnessValue}}
- </div>
- <div class="handle-item">
- <label class="handle-label">饱和度:</label>
- <el-slider v-model="handleData.saturationValue" class="info-input" :min="-100" :max="100" @change="handleImg"></el-slider>
- {{handleData.saturationValue}}
- </div>
- <div class="handle-item">
- <label class="handle-label">色调:</label>
- <el-slider v-model="handleData.hueValue" class="info-input" :min="-100" :max="100" @change="handleImg"></el-slider>
- {{handleData.hueValue}}
- </div>
- <div class="handle-item">
- <label class="handle-label">透明度:</label>
- <el-slider v-model="handleData.opacityValue" class="info-input" @change="handleImg"></el-slider>
- {{handleData.opacityValue}}
- </div>
- <div class="handle-item">
- <label class="handle-label">边框:</label>
- <el-checkbox size="small" v-model="handleData.lineFlag" @change="handleImg">是否添加边框</el-checkbox>
- </div>
- <div class="handle-item" v-if="handleData.lineFlag">
- <label class="handle-label">边框宽度:</label>
- <el-input-number size="small" v-model="handleData.lineWidth" @change="handleImg" :min="0"></el-input-number>
- </div>
- <div class="handle-item" v-if="handleData.lineFlag">
- <label class="handle-label">边框颜色:</label>
- <el-color-picker style="vertical-align: middle;" size="small" v-model="handleData.lineColor" show-alpha @change="handleImg"></el-color-picker>
- </div>
- </div>
- <!-- 6圆角设置 -->
- <template v-if="menuIndex == 6">
- <div class="handle-item">
- <label class="handle-label">角度:</label>
- <el-input-number size="small" v-model="handleData.circularValue" :min="1" :max="100"></el-input-number> %
- </div>
- </template>
- <!-- 5添加水印 -->
- <div v-if="menuIndex == 5">
- <div class="handle-item">
- <el-radio-group v-model="handleData.watermarkType">
- <el-radio-button label="1">文字水印</el-radio-button>
- <el-radio-button label="2">图片水印</el-radio-button>
- </el-radio-group>
- </div>
- <div class="handle-item" v-if="handleData.watermarkType == '1'">
- <label class="handle-label">水印类型:</label>
- <el-select size="small" v-model="handleData.watermarkStyle" style="width:150px;">
- <el-option value="1" label="单个水印"></el-option>
- <el-option value="2" label="多个水印"></el-option>
- </el-select>
- </div>
- <div v-if="handleData.watermarkType == '1'">
- <div class="handle-item">
- <label class="handle-label">文字内容:</label>
- <el-input type="text" v-model="handleData.watermarkValue" size="small" placeholder="请输入文字水印内容" style="width:150px;" @change="handleImg"></el-input>
- </div>
- <div class="handle-item">
- <label class="handle-label">文字样式:</label>
- <el-color-picker style="vertical-align: middle;" v-model="handleData.watermarkColor" show-alpha @change="handleImg"></el-color-picker>
- <el-input-number size="small" style="width: 105px;" v-model="handleData.watermarkFont" @change="handleImg" :min="0" :max="200"></el-input-number>
- </div>
- <div class="handle-item">
- <label class="handle-label">旋转角度:</label>
- <el-input-number size="small" style="width: 140px;" v-model="handleData.rotate" @change="handleImg" ></el-input-number> °
- </div>
- <div class="handle-item">
- <label class="handle-label">文字字体:</label>
- <el-select size="small" v-model="handleData.fonts" style="width:120px;" @change="handleImg">
- <el-option v-for="(item,key) in fonts" :key="key" :value="item.path" :label="item.name"></el-option>
- </el-select>
- <vxe-button type="text" status="info" icon="vxe-icon-info-circle-fill" @click="$message({message:'文字为中文时,请选择中文字体!', type:'warning'})"></vxe-button>
- </div>
- <template v-if="handleData.watermarkStyle == 2">
- <div class="handle-item" style="overflow: hidden;" v-if="handleData.watermarkType != '0'">
- <label class="handle-label">水印行数:</label>
- <el-input-number size="small" :min="1" v-model="handleData.watermarkDensityY" @change="handleImg" ></el-input-number>
- </div>
- <div class="handle-item" style="overflow: hidden;" v-if="handleData.watermarkType != '0'">
- <label class="handle-label">水印列数:</label>
- <el-input-number size="small" :min="1" v-model="handleData.watermarkDensityX" @change="handleImg" ></el-input-number>
- </div>
- </template>
- </div>
- <!-- 图片水印 -->
- <div v-if="handleData.watermarkType == '2'">
- <div class="handle-item">
- <label class="handle-label">图片水印:</label>
- <el-upload :style="{display: 'inline-block'}" action="/" :before-upload="getImgPath">
- <el-input type="text" readonly v-model="handleData.watermarkImgPath" size="small" style="width:125px;" ></el-input>
- <i class="el-icon-folder-opened open-folder" style="font-size:22px;"></i>
- </el-upload>
- </div>
- <div class="handle-item">
- <label class="handle-label">比例:</label>
- <el-input-number size="small" style="margin-right:5px;" :min="1" :max="200" v-model="handleData.watermarkImgSize" @change="handleImg" ></el-input-number>%
- </div>
- <div class="handle-item" v-if="handleData.watermarkType == '2'">
- <label class="handle-label">不透明度:</label>
- <el-input-number size="small" style="margin-right:5px;" :min="1" :max="100" v-model="handleData.watermarkImgOpactiy" @change="handleImg" ></el-input-number>
- </div>
- </div>
- <div class="handle-item" v-if="handleData.watermarkType == '2'">
- <label class="handle-label">旋转角度:</label>
- <el-input-number size="small" v-model="handleData.watermarkImgRotate" @change="handleImg" ></el-input-number>
- </div>
- <div class="handle-item" v-if="handleData.watermarkType != '0'">
- <label class="handle-label">水印位置:</label>
- <el-radio-group class="position-radio" v-model="handleData.watermarkPosition" :style="{width: '120px', color: '#fff'}" @change="handleImg">
- <el-radio :disabled="handleData.watermarkStyle == '2' && handleData.watermarkType == 1" :style="{margin: '2px 2px 2px 0', fontSize: 0}" v-for="key in watermarkPosition" :key="key" :label="key"></el-radio>
- </el-radio-group>
- <div>
- <div style="padding-bottom: 3px;">
- <label class="handle-label">水平边距:</label>
- <el-input-number size="small" v-model="handleData.watermarkX" @change="handleImg" ></el-input-number>
- </div>
- <div>
- <label class="handle-label">垂直边距:</label>
- <el-input-number size="small" v-model="handleData.watermarkY" @change="handleImg" ></el-input-number>
- </div>
- </div>
- </div>
- </div>
-
- <!-- 9批量旋转 -->
- <div v-if="menuIndex == 9">
- <div class="handle-item xuan-flex">
- <div class="xuan-item" @click="rotateChange(1)">
- <img src="../assets/image/ni.png" />
- <p>逆时针旋转90°</p>
- </div>
-
- <div class="xuan-item" @click="rotateChange(2)">
- <img src="../assets/image/shun.png" />
- <p>顺时针旋转90°</p>
- </div>
- </div>
- <div class="handle-item xuan-flex">
- <div class="xuan-item" :class="handleData.hflip == 'hflip' ? 'active' : '' " @click="flipChange('hflip')">
- <img src="../assets/image/left-right.png" />
- <p>左右翻转</p>
- </div>
-
- <div class="xuan-item" :class="handleData.vflip == 'vflip' ? 'active' : '' " @click="flipChange('vflip')">
- <img src="../assets/image/up-down.png" />
- <p>上下翻转</p>
- </div>
- </div>
-
- <div class="handle-item">
- <label class="handle-label">旋转角度:</label>
- <el-input-number size="small" :max="360" :min="-360" v-model="handleData.rotateValue" ></el-input-number> °
- </div>
-
- <div class="handle-item" style="text-align: center;">
- <el-tag type="danger">正值向右旋转,负值向左旋转</el-tag>
- </div>
- </div>
-
- <!-- 10图片裁剪 -->
- <template v-if="menuIndex == 10">
- <div class="handle-item">
- <el-radio-group v-model="cropOptions.cropType">
- <el-radio-button label="1">比例裁剪</el-radio-button>
- <el-radio-button label="2">尺寸裁剪</el-radio-button>
- </el-radio-group>
- </div>
- <div class="handle-item" style="margin: 5px 0;" v-if="cropOptions.cropType == '1'">
- <div class="handle-title">裁剪比例</div>
- <div class="flex-crop">
- <el-button class="crop-button" :type="cropOptions.fixedValue == 'free' ? 'primary' : 'default'" @click="fixedChange('free')">自由</el-button>
- <el-button class="crop-button" :type="cropOptions.fixedValue == 'original' ? 'primary' : 'default'" @click="fixedChange('original')">原图</el-button>
- <el-button class="crop-button" :type="cropOptions.fixedValue == '1:1' ? 'primary' : 'default'" @click="fixedChange('1:1')">1:1</el-button>
- <el-button class="crop-button" :type="cropOptions.fixedValue == '1:2' ? 'primary' : 'default'" @click="fixedChange('1:2')">1:2</el-button>
- <el-button class="crop-button" :type="cropOptions.fixedValue == '2:1' ? 'primary' : 'default'" @click="fixedChange('2:1')">2:1</el-button>
- <el-button class="crop-button" :type="cropOptions.fixedValue == '2:3' ? 'primary' : 'default'" @click="fixedChange('2:3')">2:3</el-button>
- <el-button class="crop-button" :type="cropOptions.fixedValue == '3:2' ? 'primary' : 'default'" @click="fixedChange('3:2')">3:2</el-button>
- <el-button class="crop-button" :type="cropOptions.fixedValue == '3:4' ? 'primary' : 'default'" @click="fixedChange('3:4')">3:4</el-button>
- <el-button class="crop-button" :type="cropOptions.fixedValue == '4:3' ? 'primary' : 'default'" @click="fixedChange('4:3')">4:3</el-button>
- <el-button class="crop-button" :type="cropOptions.fixedValue == '5:3' ? 'primary' : 'default'" @click="fixedChange('5:3')">5:3</el-button>
- <el-button class="crop-button" :type="cropOptions.fixedValue == '9:16' ? 'primary' : 'default'" @click="fixedChange('9:16')">9:16</el-button>
- <el-button class="crop-button" :type="cropOptions.fixedValue == '16:9' ? 'primary' : 'default'" @click="fixedChange('16:9')">16:9</el-button>
- </div>
- </div>
-
- <template v-if="cropOptions.cropType == '2'">
- <div class="handle-item">
- <el-radio-group size="mini" v-model="cropOptions.cropClassify" @change="classifyChange">
- <el-radio-button label="1">自定义</el-radio-button>
- <el-radio-button label="2">证件</el-radio-button>
- <el-radio-button label="3">电商</el-radio-button>
- </el-radio-group>
- </div>
- <div v-if="cropOptions.cropClassify == '2'">
- <el-button class="crop-button" style="width: 220px; margin-bottom: 10px; margin-left: 10px;" :type="cropOptions.fixedValue == '259:377' ? 'primary' : 'default'" @click="fixedChange('259:377')">
- 小一寸259x377px | 2.2x3.3cm
- <p style="opacity: 0.6; margin-top: 6px;">驾驶证、体检表等</p>
- </el-button>
- <el-button class="crop-button" style="width: 220px; margin-bottom: 10px;" :type="cropOptions.fixedValue == '295:413' ? 'primary' : 'default'" @click="fixedChange('295:413')">
- 一寸295x413px | 2.5x3.5cm
- <p style="opacity: 0.6; margin-top: 6px;">学生证、健康证等</p>
- </el-button>
- <el-button class="crop-button" style="width: 220px; margin-bottom: 10px;" :type="cropOptions.fixedValue == '390:567' ? 'primary' : 'default'" @click="fixedChange('390:567')">
- 大一寸390x567px | 3.3x4.8cm
- <p style="opacity: 0.6; margin-top: 6px;">护照、港澳通行证等</p>
- </el-button>
- <el-button class="crop-button" style="width: 220px; margin-bottom: 10px;" :type="cropOptions.fixedValue == '413:531' ? 'primary' : 'default'" @click="fixedChange('413:531')">
- 小二寸413x531px | 3.5x4.5cm
- <p style="opacity: 0.6; margin-top: 6px;">个人简历、考试报名</p>
- </el-button>
- <el-button class="crop-button" style="width: 220px; margin-bottom: 10px;" :type="cropOptions.fixedValue == '413:579' ? 'primary' : 'default'" @click="fixedChange('413:579')">
- 二寸413x579px | 3.5x4.9cm
- <p style="opacity: 0.6; margin-top: 6px;">公务员考试、部分签证等</p>
- </el-button>
- </div>
- <div v-if="cropOptions.cropClassify == '3'">
- <el-button class="crop-button" style="width: 220px; margin-bottom: 10px; margin-left: 10px;" :type="cropOptions.fixedValue == '1920:500' ? 'primary' : 'default'" @click="fixedChange('1920:500')">
- 首页横幅 1920x500
- </el-button>
- <el-button class="crop-button" style="width: 220px; margin-bottom: 10px;" :type="cropOptions.fixedValue == '750:800' ? 'primary' : 'default'" @click="fixedChange('750:800')">
- 详情页 750x800
- </el-button>
- <el-button class="crop-button" style="width: 220px; margin-bottom: 10px;" :type="cropOptions.fixedValue == '800:800' ? 'primary' : 'default'" @click="fixedChange('800:800')">
- 产品主图 800x800
- </el-button>
- <el-button class="crop-button" style="width: 220px; margin-bottom: 10px;" :type="cropOptions.fixedValue == '1920:120' ? 'primary' : 'default'" @click="fixedChange('1920:120')">
- 店招 1920x120
- </el-button>
- <el-button class="crop-button" style="width: 220px; margin-bottom: 10px;" :type="cropOptions.fixedValue == '750:500' ? 'primary' : 'default'" @click="fixedChange('750:500')">
- 首页横幅 750x500
- </el-button>
- <el-button class="crop-button" style="width: 220px; margin-bottom: 10px;" :type="cropOptions.fixedValue == '740x352' ? 'primary' : 'default'" @click="fixedChange('740:352')">
- 商品主图 740x352
- </el-button>
- <el-button class="crop-button" style="width: 220px; margin-bottom: 10px;" :type="cropOptions.fixedValue == '640x320' ? 'primary' : 'default'" @click="fixedChange('640:320')">
- 手机详情页 640x320
- </el-button>
- </div>
- <template v-if="cropOptions.cropClassify == '1'">
- <div class="handle-title">裁剪尺寸</div>
- <div class="handle-item">
- <label class="handle-label">宽度:</label>
- <el-input-number size="small" :min="1" v-model="virtualWidth" @change="cropWidthChange"></el-input-number> px
- </div>
- <div class="handle-item">
- <label class="handle-label">高度:</label>
- <el-input-number size="small" :min="1" v-model="virtualHeight" @change="cropHeightChange"></el-input-number> px
- </div>
- <div class="handle-item">
- <label class="handle-label">锁定比例:</label>
- <el-checkbox v-model="cropOptions.fixed"></el-checkbox>
- <span style="font-size: 12px; color: #666;">(原始尺寸{{cropOptionsImgInfo.originalWidth}}:{{cropOptionsImgInfo.originalHeight}})</span>
- </div>
- </template>
- </template>
-
- <div style="text-align: center;">
- <el-badge v-if="cropOptions.cropType == '2' && cropOptions.cropClassify != '1'" is-dot style="font-size: 12px;">裁剪尺寸大于原图尺寸时,会等比例放大原图后进行裁剪</el-badge>
- <el-button style="margin: 20px 0;" type="info" @click="setModal = true;">应用全部</el-button>
- <el-button type="info" plain @click="resetModal = true;">重置设置</el-button>
- </div>
-
- <div class="handle-item" style="text-align: center;">
- <el-tag type="danger">批量裁剪请点击“应用全部”按钮</el-tag>
- </div>
- </template>
- </div>
- </div>
- </div>
- </div>
- </template>
-
- <!-- 8图片拼接 -->
- <template v-if="menuIndex == 8">
- <div class="soft-content">
- <div class="content-left" style="width: calc(100% - 270px)">
- <div class="merge-flex">
- <draggable class="merge-scroll" tag="div" v-model="mergeList" :animation="200" :scroll="true" @end="dragEnd" >
- <div class="merge-item" v-for=" (item, index) in mergeList" :key="index">
- <div class="img-area">
- <div style="width: 100%;height: 100%; flex: 1;position: relative;">
- <i class="el-icon-close merge-imgdel" @click="deleteMerge(index)"></i>
- <img :src="item.path" class="mergelist-img">
- </div>
- </div>
- <p :title="item.name" class="merge-name overflow">{{item.name}}</p>
- </div>
- </draggable>
- <div class="merge-content">
- <div class="merge-top">
- <div style="line-height: 34px;color: #333;">
- {{mergeList.length}} / <span style="color: #999;">100</span>
- <!-- <vxe-button type="text" status="info" icon="vxe-icon-info-circle-fill" @click="$message({message:'上下拖动左侧图片可调整前后顺序', type:'warning'})"></vxe-button> -->
- </div>
- <div class="action-right" v-if="mergeData.sortType == 3">
- <div class="action-ritem" @click="zoom('reduce')">
- <i class="el-icon-zoom-out" style="font-size: 20px;"></i>
- <p>缩小</p>
- </div>
- <div class="action-ritem" @click="zoom('enlarge')">
- <i class="el-icon-zoom-in" style="font-size: 20px;"></i>
- <p>放大</p>
- </div>
- </div>
- </div>
- <div class="mlist-scroll bgmini">
- <!-- 横图 -->
- <div class="horizontal-scroll" v-if="mergeData.sortType == 1" :style="'padding: '+ hBorder + 'px;background-color:'+mergeData.backgroundColor+';'">
- <div class="horizontal-content" id="horizontal-content">
- <img class="horizontal-img" :id="'horizontal-img-'+key" v-for="(item, key) in mergeList" :key="key" :style="'border-radius:'+ mergeData.radius / 2 +'%;margin-right:' + hSpace + 'px;'" :src="item.path" />
- </div>
- </div>
-
- <!-- 竖图 -->
- <div class="vertical-content" id="vertical-content" v-if="mergeData.sortType == 2" :style="'padding: '+ vBorder + 'px;background-color:'+mergeData.backgroundColor+';'">
- <img class="vertical-img" v-for="(item, key) in mergeList" :key="key" :style="'border-radius:'+ mergeData.radius / 2 +'%;margin-bottom:' + vSpace + 'px;'" :src="item.path" />
- </div>
-
- <!-- 自定义 -->
- <div v-if="mergeData.sortType == 3" class="mlist-content" :style="mergeData.autoStyle+'transform: scale('+mergeData.zoom+')'">
- <div id="mlist-area" class="mlist-area" :style="'padding: '+ mergeData.border / 10 + '%;background-color:'+mergeData.backgroundColor+';'">
- <div class="merge-row" :style="blockStyle('height')" v-for="row in mergeData.row" :key="row">
- <div v-if="mergeData.mergeType == 2" class="merge-col" :style="blockStyle('width')" v-for="col in mergeData.col" :key="col">
- <img @mouseover="move((row-1)*mergeData.col+col-1)" :id="'merge-imgId-'+Number((row-1)*mergeData.col+col-1)"
- class="merge-img" v-if="mergeList.length > (row-1)*mergeData.col+col-1"
- :src="mergeList[Number((row-1)*mergeData.col+col-1)].path"
- :style="picStyle(Number((row-1)*mergeData.col+col-1))" />
- <div v-else class="merge-add" @click="pickFile()">+</div>
- </div>
- <div v-if="mergeData.mergeType == 1" class="merge-col" :style="blockStyle('width')" v-for="col in mergeData.col" :key="col">
- <img @mouseover="move((row-1)*mergeData.col+col-1)" :id="'merge-imgId-'+Number((row-1)*mergeData.col+col-1)"
- class="merge-img2" v-if="mergeList.length > (row-1)*mergeData.col+col-1"
- :src="mergeList[Number((row-1)*mergeData.col+col-1)].path" />
- <div v-else class="merge-add" @click="pickFile()">+</div>
- <span v-if="mergeList.length > (row-1)*mergeData.col+col-1" :style="picStyle(Number((row-1)*mergeData.col+col-1))" class="disnone"></span>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
-
- <div class="content-right" style="width: 260px;">
- <div class="setting-area">
- <div class="img-handle">
- <div class="handle-item">
- <el-radio-group v-model="mergeData.sortType" @change="sortChange" size="small">
- <el-radio-button :label="2">拼长竖图</el-radio-button>
- <el-radio-button :label="1">拼长横图</el-radio-button>
- <el-radio-button :label="3">自定义</el-radio-button>
- </el-radio-group>
- </div>
- <div class="handle-item" v-if="mergeData.sortType == 3">
- <label class="handle-label">画布尺寸:</label>
- <el-select size="small" v-model="mergeData.sizeType" style="width:150px;" @change="canvasChange">
- <el-option value="1200*1200px(1:1)"></el-option>
- <el-option value="1200*1800px(2:3)"></el-option>
- <el-option value="1800*1200px(3:2)"></el-option>
- <el-option value="1200*1600px(3:4)"></el-option>
- <el-option value="1600*1200px(4:3)"></el-option>
- <el-option value="1920*1080px(16:9)"></el-option>
- <el-option value="1080*1920px(9:16)"></el-option>
- </el-select>
- </div>
- <div class="handle-item">
- <label class="handle-label">画布宽度:</label>
- <el-input-number size="small" style="width: 140px;" :max="10000" :min="1" v-model="mergeData.outWidth" @change="outWidthChange" ></el-input-number>
- <i class="el-icon-connection" style="font-size: 16px;position: absolute;left: 20px; bottom: -6px;"></i>
- </div>
- <div class="handle-item">
- <label class="handle-label">画布高度:</label>
- <el-input-number size="small" style="width: 140px;" :max="10000" :min="1" v-model="mergeData.outHeight" @change="outHeightChange" ></el-input-number>
- </div>
- <div class="handle-item" v-if="mergeData.sortType != 3">
- <label class="handle-label">原图比例:</label>
- <el-input v-model="mergeData.width" :disabled="true" size="small" style="width: 70px;"></el-input>
- <!-- <el-input-number :disabled="mergeData.sortType != 3" size="small" style="width: 70px;" :max="10000" :min="1" v-model="mergeData.width" @change="widthChange" ></el-input-number> -->
- <i class="el-icon-connection" style="font-size: 16px;"></i>
- <!-- <el-input-number :disabled="mergeData.sortType != 3" size="small" style="width: 70px;" :max="10000" :min="1" v-model="mergeData.height" @change="heightChange" ></el-input-number> -->
- <el-input v-model="mergeData.height" :disabled="true" size="small" style="width: 70px;"></el-input>
- </div>
- <div class="handle-item" v-if="mergeData.sortType == 3">
- <label class="handle-label">锁定比例:</label>
- <el-checkbox v-model="mergeData.lockScale"></el-checkbox>
- </div>
- <div class="handle-item" v-if="mergeData.sortType == 3">
- <label class="handle-label">拼接模式:</label>
- <el-radio-group size="small" v-model="mergeData.mergeType" style="vertical-align: inherit;">
- <el-radio :label="1">自适应</el-radio>
- <el-radio :label="2">裁剪</el-radio>
- </el-radio-group>
- </div>
- <div class="handle-item" v-if="mergeData.sortType == 3">
- <label class="handle-label">行数:</label>
- <el-input-number size="small" style="width: 110px;" :max="50" :min="1" v-model="mergeData.row" @change="rowColChange" ></el-input-number>
- </div>
- <div class="handle-item" v-if="mergeData.sortType == 3">
- <label class="handle-label">列数:</label>
- <el-input-number size="small" style="width: 110px;" :max="50" :min="1" v-model="mergeData.col" @change="rowColChange" ></el-input-number>
- </div>
- <div class="handle-item">
- <label class="handle-label">间距:</label>
- <el-input-number size="small" style="width: 110px;" :max="100" :min="0" v-model="mergeData.space" @blur="numBlur('space')" @change="sizeChange" ></el-input-number> %
- </div>
- <div class="handle-item">
- <label class="handle-label">边距:</label>
- <el-input-number size="small" style="width: 110px;" :max="100" :min="0" v-model="mergeData.border" @blur="numBlur('border')" @change="sizeChange" ></el-input-number> %
- </div>
- <div class="handle-item">
- <label class="handle-label">圆角:</label>
- <el-input-number size="small" style="width: 110px;" :max="100" :min="0" v-model="mergeData.radius" @blur="numBlur('radius')" ></el-input-number> %
- </div>
- <div class="handle-item">
- <label class="handle-label">背景:</label>
- <el-color-picker size="small" style="vertical-align: middle;" v-model="mergeData.backgroundColor" show-alpha></el-color-picker>
- </div>
-
- </div>
- </div>
- </div>
- </div>
- </template>
-
- <!-- 底部设置区域 -->
- <div class="img-footer-area">
- <div class="handle-item" v-if="menuIndex == 7">
- <label class="handle-label" style="width:80px;">起始编号:</label>
- <el-input-number size="small" style="width: 110px;" :min="0" v-model="handleRename.startNumber" @change="setChange" ></el-input-number>
-
- <label class="handle-label">增量:</label>
- <el-input-number size="small" style="width: 110px;" v-model="handleRename.increment" @change="setChange" ></el-input-number>
- <span class="i-desc font-12">(后一位编号增加的值)</span>
-
- <label class="handle-label">位数:</label>
- <el-input-number size="small" style="width: 110px;" v-model="handleRename.digit" @change="setChange" ></el-input-number>
- <span class="i-desc font-12">(例:001的编号位数为3)</span>
- </div>
- <div class="footer-line-between">
- <!-- 1格式转化 -->
- <div class="handle-item" v-if="menuIndex == 1">
- <label class="handle-label">输出转换:</label>
- <el-select v-model="handleData.imgFormat" style="width:100px;" size="small">
- <el-option v-for="(item, key) in imgFormat" :key="key" :value="item" :label="item"></el-option>
- </el-select>
- <vxe-button v-if="handleData.imgFormat == 'ICO'" type="text" status="info" icon="vxe-icon-info-circle-fill" @click="$message('图标资源ICO有最大尺寸限制,建议尺寸低于512x512')"></vxe-button>
- <vxe-button v-if="isGif" type="text" status="info" icon="vxe-icon-info-circle-fill" @click="$message('GIF图片默认输出第一帧,多帧输出到单独文件夹中')"></vxe-button>
- <el-checkbox v-if="isGif" v-model="gifChecked">GIF图片输出所有帧</el-checkbox>
- </div>
- <!-- 2图片压缩 -->
- <div class="handle-item" v-if="menuIndex == 2">
- <label class="handle-label">压缩质量:</label>
- <el-input-number v-model="handleData.quality" :min="1" :max="100" size="small"></el-input-number>
- <el-tag size="mini" type="danger" style="margin-left: 10px;">质量越低压缩的越小</el-tag>
- </div>
- <!-- 11修改dpi -->
- <div class="handle-item" v-if="menuIndex == 11">
- <label>将图片DPI更改为:</label>
- <el-select v-model="handleData.dpi" style="width:100px;" size="small">
- <el-option :value="72" label="72DPI"></el-option>
- <el-option :value="96" label="96DPI"></el-option>
- <el-option :value="150" label="150DPI"></el-option>
- <el-option :value="200" label="200DPI"></el-option>
- <el-option :value="300" label="300DPI"></el-option>
- <el-option :value="350" label="350DPI"></el-option>
- <el-option :value="500" label="500DPI"></el-option>
- <el-option :value="1000" label="1000DPI"></el-option>
- </el-select>
- <vxe-button type="text" status="info" icon="vxe-icon-info-circle-fill" @click="$message({message:'提高分辨率(DPI)不能让模糊的图片变清晰,也不会改变照片的高宽像素等属性', type:'warning'})"></vxe-button>
- </div>
-
- <!-- 8图片拼接 -->
- <div v-if="menuIndex == 8">
- <el-tag type="danger">拖动左侧列表中的图片可以调整拼接顺序</el-tag>
- </div>
-
- <!-- 7重命名 -->
- <div v-if="menuIndex == 7">
- <div class="handle-item" >
- <label class="handle-label" style="width: 80px;">新图片名:</label>
- <el-input type="text" v-model="handleRename.fileName" size="small" placeholder="请输入新图片名" style="width:200px;" @change="setChange"></el-input>
- </div>
- </div>
- <div v-else> </div>
-
- <div>
- <span>保存目录:</span>
- <el-input :title="handleData.newPath" ref="upload-input" @focus="pickPath" placeholder="请选择输出目录" size="small" v-model="handleData.newPath" readonly style="width:180px;" prefix-icon="el-icon-folder"></el-input>
- <el-popover placement="bottom" popper-class="popper-open" trigger="hover" content="打开保存目录">
- <i class="el-icon-folder-opened" slot="reference" style="padding-left: 5px; cursor: pointer; font-size: 22px; vertical-align: middle;" @click="openFolder()"></i>
- </el-popover>
- <el-button type="danger" style="margin: 0 20px;" @click="exportImg()" :loading="loading">开始转换</el-button>
- </div>
- </div>
- </div>
-
- </div>
-
- </template>
- </el-main>
- <el-footer height="48px">
- <!-- 更新 -->
- <soft-update ref="updateRef" :showDowload="dowloadModel"
- :dowloadFinish="finishModel"></soft-update>
- </el-footer>
- </el-container>
- </el-container>
- </el-container>
-
- <!-- <el-dialog title="图片预览" :visible.sync="imgShow" :fullscreen="true">
- <div style="width:100%;height:100%;overflow: auto;text-align:center">
- <img draggable="false" :src="imgSrc"
- :style="{borderRadius: menuIndex == 6 ? handleData.circularValue : 0 +'%', 'maxWidth': '100%','maxHeight':'100%',transform: 'rotate('+handleData.rotateValue+'deg) rotateY('+ (handleData.hflipflip ? '180' : '0') +'deg) rotateX('+ (handleData.vflip ? '180' : '0') +'deg) scale('+handleData.scaling/100+')'}"/>
- </div>
- </el-dialog> -->
-
- <el-dialog title="截图预览" :visible.sync="cropimgShow" :fullscreen="true">
- <div v-html="cropOptions.previewInfo" style="margin: auto;"></div>
- </el-dialog>
-
- <el-dialog title="温馨提示" :visible.sync="setModal">
- <p>是否将当前图片的裁剪设置应用到所有图片?</p>
- <span slot="footer">
- <el-button @click="setModal = false">取 消</el-button>
- <el-button type="primary" @click="setOk()">确 定</el-button>
- </span>
- </el-dialog>
-
- <el-dialog title="温馨提示" :visible.sync="resetModal">
- <p>是否重置所有图片的裁剪设置?</p>
- <span slot="footer">
- <el-button @click="resetModal = false">取 消</el-button>
- <el-button type="primary" @click="resetOk()">确 定</el-button>
- </span>
- </el-dialog>
-
- <el-dialog :visible.sync="renameModal" width="400px">
- <el-result icon="success" title="处理完成" :subTitle="subTitle">
- <template slot="extra">
- <el-button type="primary" @click="renameModal = false;">确定</el-button>
- </template>
- </el-result>
- </el-dialog>
- </div>
-
- </template>
- <script>
- import os from 'os'
- import fs from 'fs'
- import pathMod, { resolve } from 'path';
- import electronApi from '@/utils/electronApi';
- import softUpdate from './update.vue';
- import softHeader from './header.vue';
- import pjson from '/package.json'
- import Draggable from 'vuedraggable'
- import Vue from 'vue'
- import { VueCropper } from 'vue-cropper'
- const sizeOf = require('image-size')
- let separator = '';
- if (os.platform == 'linux') {
- separator = '/'
- } else {
- separator = '\\'
- }
- export default {
- name: 'landing-page',
- components: {
- softUpdate,
- softHeader,
- Draggable,
- VueCropper
- },
- data() {
- return {
- isGif: false, //是否含有gif图片
- gifChecked: false, // 是否输出所有帧
- rollFlag: false,
- viewScale: 1,
- productName: pjson.softInfo.softName,
- setModal: false,
- resetModal: false,
- renameModal: false,
- subTitle: '请查看列表文件状态',
- cropimgShow: false,
- cropImgIndex: -1,
- cropInt: false,
- selectInt: false,
- cropImgLoading: false,
- virtualWidth: 0,
- virtualHeight: 0,
- cropOptionsImgInfo: {},
- cropOptions: {
- img: '',
- autoCrop: true, // 是否默认生成截图框
- autoCropWidth: 100,
- autoCropHeight: 100,
- cropWidth: 100,
- cropHeight: 100,
- original: false,
- maxImgSize: 20000,
- canMove: false,
- centerBox: true, // 截图框是否被限制在图片里面
- fixed: false, //是否开启截图框宽高固定比例
- fixedValue: 'free',
- cropType: '1',
- cropClassify: '1',
- fixedNumber: [1, 1],
- infoTrue: true,
- previewInfo: '',
- cropScale: 100,
- },
- execLimit: 3,
- defaultFont:'c:\\windows\\fonts\\simkai.ttf',
- imgShow:false,
- pickProgress:false,
- pickProgressPercent:0,
- fonts:[],
- watermarkPosition:['NorthWest','North','NorthEast','West','Center','East','SouthWest','South','SouthEast'],
- imgUrl: this.$api.imgUrl,
- imgSrc: '',
- imgList: [],
- mergeList: [], // 拼接图片列表
- cropList: [], // 裁剪图片列表
- imgInfo: '',
- imgInfoIndex: 0,
- menuIndex: 1, // 选中菜单
- imgFormat: ['PNG','BMP','JPEG','JPG','ICO','WBMP','WEBP','HEIC','GIF','JFIF','TTF','TIF','TIFF','SVG','3FR','3G2','3GP','AAI','AI','ART','ARW','BGR','BGRA','BGRO','BIE','BMP2','BMP3','BRF','CAL','CALS','CANVAS','CAPTION','CIN','CIP','CLIP','CMYK','CMYKA','CR2','CRW','CUR','CUT','DATA','DCM','DCR','DCX','DDS','DFONT','DJVU','DNG','DOT','DPX','DXT1','DXT5','EPDF','EPI','EPS','EPS2','EPS3','EPSF','EPSI','EPT','EPT2','EPT3','ERF','EXR','FAX','FILE','FITS','FRACTAL','FTP','FTS','G3','G4','GIF87','GRADIENT','GRAY','GRAYA','GROUP4','GV','H','HALD','HDR','HISTOGRAM','HRZ','ICB','ICON','IIQ','INFO','INLINE','IPL','ISOBRL','ISOBRL6','J2C','J2K','JBG','JBIG','JNG','JNX','JP2','JPC','JPE','JPM','JPS','JPT','JSON','K25','KDC','LABEL','M2V','M4V','MAC','MAGICK','MAP','MASK','MAT','MATTE','MEF','MIFF','MKV','MNG','MONO','MRW','MSL','MSVG','MVG','NEF','NRW','ORF','OTB','OTF','PAL','PALM','PAM','PANGO','PATTERN','PBM','PCD','PCDS','PCL','PCT','PEF','PES','PFA','PFB','PFM','PGM','PGX','PICON','PICT','PIX','PJPEG','PLASMA','PNG00','PNG24','PNG32','PNG48','PNG64','PNG8','PNM','PPM','PREVIEW','PS','PS2','PS3','PSB','PSD','PTIF','PWP','RADIAL-GRADIENT','RAF','RAS','RAW','RGB','RGBA','RGBO','RGF','RLA','RLE','RMF','RW2','SCR','SCT','SFW','SGI','SHTML','SIX','SIXEL','SPARSE-COLOR','SR2','SRF','STEGANO','SUN','SVGZ','TGA','THUMBNAIL','TIFF64','TILE','UBRL','UBRL6','UIL','UYVY','VDA','VICAR','VID','VIFF','VIPS','VST','WMF','WMV','WMZ','WPG','X','X3F','XBM','XC','XCF','XPM','XPS','XV','XWD','YCbCr','YCbCrA','YUV'], // 图片格式
- positionList: ['上左', '上中', '上右', '中左', '中间', '中右', '下左', '下中', '下右'],
- downloadDir: '', // 默认下载目录
- softdownloadDir: '', // 软件下载目录
- mergeData: {
- space: 0,
- border: 0,
- radius: 0,
- row: 2,
- col: 2,
- width: 1200,
- height: 1200,
- contentWidth: 0,
- contentHeight: 0,
- outWidth: 1200,
- outHeight: 1200,
- backgroundColor: 'rgba(255,255,255,1)',
- sizeType: '1200*1200px(1:1)',
- scale: '1:1',
- zoom: 1,
- lockScale: true,
- autoStyle: 'padding-top: 50%;',
- mergeType: 2,
- sortType: 2
- },
- handleData: {
- dpi: 300,
- width: 0,
- height: 0,
- pathType: '2', // 输出目录类型
- newPath: os.userInfo().homedir + separator + "Downloads", // 新路径
- autoRename: false, // 是否自动重命名
- imgFormat: 'JPG', // 转换类型
- quality: 92, // 图片品质
- colorNum:256, // 颜色数量 1 - 256
- sizeType: '1', // 调整尺寸
- scaling: 100, // 缩放比例
- rotateValue: 0, // 旋转角度
- color: '0', // 图片色彩
- colorValue: 256,
- paintValue: 1, //油画数值
- brightnessValue: 0, // 亮度
- saturationValue: 0, //饱和度
- hueValue: 0, // 色调
- contrastValue: 0, // 对比度
- opacityValue: 100, // 透明度
- compressScaling:100,
- compressOutType:2,
- watermarkType: '1', // 水印类型 1文字 2图片
- watermarkStyle: '1', // 1 单个 2平铺
- watermarkValue: '', // 水印文字内容
- watermarkColor: '#ff0000',
- watermarkFont: 16,
- watermarkX: 0,
- watermarkY: 0,
- watermarkDensityX: 3, // 平铺水印密度
- watermarkDensityY: 3, // 平铺水印密度
- watermarkImgPath: '', //图片水印路径
- watermarkImgOpactiy: 100, // 水印不透明度
- watermarkImgSize: 100, // 水印缩放比例
- watermarkImgRotate: 0,
- watermarkPosition: 'Center', // 水印位置
- lineFlag: false,
- lineWidth: 3,
- lineColor: '#ff0000',
- fonts:'',
- rotate: 30,
- circularFlag: false,
- circularValue: 10,
- hflip: false,
- vflip: false,
- lockScale: true,
- },
- handleRename: {
- fileName: "", // 新文件名
- fileCase: "1", // 大小写转换
- startNumber: 0, // 起始编号
- increment: 1, // 增量
- digit: 1 // 位数
- },
- dowloadModel: false,
- finishModel: false,
- version: '0.0.1',
-
- isStart: false, // 是否开始转换
- isUpdate: false, // 是否有更新
-
- loading: false,
- cancelLoadStatus: false,
- authority:{}, // 用户权限
- sysDefaultTmpPath:'', // 系统水印路径
- previewTmpPath:'', // 预览图片路径
- imgLoading:false,
- renameLoading: false,
- mergeLoading: false,
- mergeInterval: false,
- };
- },
- computed:{
- hBorder: {
- get(){
- return 250 * this.mergeData.border / 500;
- }
- },
- hSpace: {
- get(){
- return 250 * this.mergeData.space / 500;
- }
- },
- vBorder: {
- get(){
- return 250 * this.mergeData.border / 500;
- }
- },
- vSpace: {
- get(){
- return 250 * this.mergeData.space / 500;
- }
- }
- },
- mounted() {
- this.$refs.updateRef.updateSoft(true);
-
- let __dirname = os.userInfo().homedir;
- this.softdownloadDir = __dirname + separator + "Downloads";
- if(fs.existsSync(__dirname + separator + "Desktop")){
- this.downloadDir = __dirname + separator + "Desktop"
- } else{
- this.downloadDir = __dirname + separator + "Downloads"
- }
- this.handleData.newPath = this.downloadDir;
- // 预览图片路径
- this.previewTmpPath = os.tmpdir()+separator+'preview.png';
- this.fonts = [
- {
- name:'宋体',
- path:'c:\\Windows\\fonts\\simsun.ttc',
- },
- {
- name:'仿宋',
- path:'c:\\windows\\fonts\\simfang.ttf',
- },
- {
- name:'新宋体',
- path:'c:\\windows\\fonts\\simsun.ttc',
- },
- {
- name:'楷体',
- path:'c:\\windows\\fonts\\simkai.ttf',
- },
- {
- name:'微软雅黑 常规',
- path:'C:\\Windows\\Fonts\\msyh.ttc',
- },
- {
- name:'微软雅黑 粗体',
- path:'c:\\windows\\fonts\\msyhbd.ttc'
- }
- ];
- this.defaultFont = 'c:\\windows\\fonts\\simkai.ttf';
- // 打开浏览器
- const links = document.querySelectorAll('a[href]');
- links.forEach(link => {
- link.addEventListener('click', e => {
- const url = link.getAttribute('href');
- e.preventDefault();
- electronApi.call('openExternal', [url]);
- });
- });
- this.initDrop();
- },
- methods: {
- // 鼠标滚轮事件
- initRoll(){
- let element = document.getElementById('show-img');
- if(!this.rollFlag){
- // 添加滚轮事件监听器
- element.addEventListener('wheel', (event) => {
- this.rollFlag = true;
- // event.deltaY 是滚轮滚动的距离,正值表示向下滚动,负值表示向上滚动
- if (event.deltaY < 0) {
- if(this.viewScale < 5){
- this.viewScale += 0.1;
- }
- } else {
- if(this.viewScale > 0){
- this.viewScale -= 0.1;
- }
- }
- event.preventDefault();
- });
- }
-
- },
- // 选择目录
- pickPath() {
- this.$refs['upload-input'].blur();
- electronApi.call('pickDir', []).then((path) => {
- if (path) {
- this.handleData.newPath = path;
- this.downloadDir = path;
- }
- });
- },
- // 将裁剪设置应用到所有图片
- setOk(){
- let cropPosition = this.cropList[this.cropImgIndex].cropPosition;
- this.cropList.map(item => {
- item.cropPosition = cropPosition;
- item.cropOptions = this.cropOptions;
- });
- setTimeout(()=>{
- this.setModal = false;
- }, 2000);
- },
- // 重置所有裁剪设置
- resetOk(){
- this.cropList.map(item => {
- item.cropPosition = undefined;
- item.cropOptions = {};
- });
- this.cropOptions.fixedValue = 'free';
- this.cropOptions.fixed = false;
- this.cropOptions.fixedNumber = [this.cropOptionsImgInfo.width, this.cropOptionsImgInfo.height];
- setTimeout(()=>{
- this.resetModal = false;
- }, 500);
- },
- // 选择裁剪比例
- fixedChange(e){
- this.cropOptions.fixedValue = e;
- if(e == 'free'){
- this.cropOptions.fixed = false;
- }else if(e == 'original'){
- this.cropOptions.fixed = true;
- this.cropOptions.fixedNumber = [this.cropOptionsImgInfo.originalWidth, this.cropOptionsImgInfo.originalHeight];
- }else{
- this.cropOptions.fixed = true;
- this.cropOptions.fixedNumber = [e.split(':')[0], e.split(':')[1]];
- }
- setTimeout(() => {
- this.$refs.cropper.goAutoCrop();
- this.$nextTick(() => {
- this.cropOptions.autoCropWidth = Number(this.$refs.cropper.cropW.toFixed(0));
- this.cropOptions.autoCropHeight = Number(this.$refs.cropper.cropH.toFixed(0));
- });
- }, 100);
- },
- // 加载图片成功回调函数
- cropImgLoad(result){
- this.cropImgLoading = result;
- if(this.cropList[this.cropImgIndex].cropPosition){ // 有位置信息
- this.$refs.cropper.goAutoCrop();
- this.$nextTick(() => {
- let width = this.cropList[this.cropImgIndex].cropPosition.x2 - this.cropList[this.cropImgIndex].cropPosition.x1;
- let height = this.cropList[this.cropImgIndex].cropPosition.y2 - this.cropList[this.cropImgIndex].cropPosition.y1;
- this.$refs.cropper.cropOffsertX = this.cropList[this.cropImgIndex].cropPosition.x1;
- this.$refs.cropper.cropOffsertY = this.cropList[this.cropImgIndex].cropPosition.y1;
- this.$refs.cropper.cropW = width;
- this.$refs.cropper.cropH = height;
- });
- }else{
- let imgPosition = this.$refs.cropper.getImgAxis();
- this.cropOptions.autoCropWidth = imgPosition.x2 - imgPosition.x1;
- this.cropOptions.autoCropHeight = imgPosition.y2 - imgPosition.y1;
- }
- },
- // 实时预览
- realTime(data){
- clearInterval(this.cropInt);
- this.cropOptions.previewInfo = data.html;
- if(this.cropImgLoading){
- this.getCropInfo(data);
- }else{
- this.cropInt = setInterval(()=> {
- if(this.cropImgLoading){
- this.getCropInfo(data);
- clearInterval(this.cropInt);
- }
- }, 300);
- }
- },
- getCropInfo(data){
- if(this.cropOptions.cropType == '2' && this.cropOptions.cropClassify != '1'){
- document.getElementsByClassName('crop-info')[0].style.opacity = 0;
- }else{
- document.getElementsByClassName('crop-info')[0].style.opacity = 1;
- }
- setTimeout(() => {
- this.cropOptions.previewInfo = data.html;
- let w = document.getElementsByClassName('crop-info')[0].innerText.split(' × ')[0];
- let h = document.getElementsByClassName('crop-info')[0].innerText.split(' × ')[1];
- let w_px = document.getElementsByClassName('cropper-crop-box')[0].offsetWidth;
- let h_px = document.getElementsByClassName('cropper-crop-box')[0].offsetHeight;
-
- let scale = w_px / w * 100;
- this.cropOptions.cropWidth = Number(w);
- this.cropOptions.cropHeight = Number(h);
- this.cropOptions.cropScale = Number(scale);
-
- let cropPosition = this.$refs.cropper.getCropAxis(); //截图框位置信息
- let imgPosition = this.$refs.cropper.getImgAxis();
- let dis_x = cropPosition.x1 < imgPosition.x1 ? 0 : cropPosition.x1 - imgPosition.x1;
- let dis_y = cropPosition.y1 < imgPosition.y1 ? 0 : cropPosition.y1 - imgPosition.y1;
-
- let cropX = dis_x / (this.cropOptions.cropScale / 100);
- let cropY = dis_y / (this.cropOptions.cropScale / 100);
-
- cropPosition.cropX = cropX; // 裁剪图片真实尺寸
- cropPosition.cropY = cropY;
- cropPosition.cropWidth = w;
- cropPosition.cropHeight = h;
- this.virtualWidth = Number(w);
- this.virtualHeight = Number(h);
-
- this.cropList[this.cropImgIndex].cropPosition = cropPosition;
- this.cropList[this.cropImgIndex].cropOptions = JSON.parse(JSON.stringify(this.cropOptions));
- }, 200);
-
- },
- selectTabCrop(data){
- this.selectCropImg(data.rowIndex);
- },
- // 选择图片
- selectCropImg(index){
- this.cropImgIndex = index;
- if(this.cropList[index].cropOptions){
- this.cropOptions = JSON.parse(JSON.stringify(this.cropList[index].cropOptions));
- }else{
- this.setDefaultCropData();
- }
- this.cropOptions.img = this.cropList[index].path;
- this.cropOptionsImgInfo = this.cropList[index];
- this.cropImgLoading = false;
- this.$forceUpdate();
- },
- // 裁剪分类
- classifyChange(e){
- if(e == '1'){ // 自定义
- this.virtualWidth = this.cropOptionsImgInfo.originalWidth;
- this.virtualHeight = this.cropOptionsImgInfo.originalHeight;
- this.cropOptions.fixed = false;
- this.cropOptions.fixedValue = 'free';
- this.$refs.cropper.goAutoCrop();
- this.$nextTick(() => {
- this.cropOptions.autoCropWidth = Number(this.virtualWidth);
- this.cropOptions.autoCropHeight = Number(this.virtualHeight);
- });
- }
- },
- cropWidthChange(e){
- let scale = Number(this.cropOptionsImgInfo.originalWidth) / Number(this.cropOptionsImgInfo.originalHeight);
- if(this.cropOptions.fixed){ // 锁定比例
- this.virtualHeight = Math.round(this.virtualWidth / scale);
- }
- let cropPosition = this.$refs.cropper.getCropAxis();
- let c_w = cropPosition.x2 - cropPosition.x1;
- let c_h = cropPosition.y2 - cropPosition.y1;
-
- let w = document.getElementsByClassName('crop-info')[0].innerText.split(' × ')[0];
- let h = document.getElementsByClassName('crop-info')[0].innerText.split(' × ')[1];
- let c_scale = w / c_w;
-
- this.$refs.cropper.goAutoCrop();
- this.$nextTick(() => {
- this.cropOptions.autoCropWidth = this.virtualWidth / c_scale;
- this.cropOptions.autoCropHeight = this.virtualHeight / c_scale;
- });
-
- },
- cropHeightChange(e){
- let scale = Number(this.cropOptionsImgInfo.originalWidth) / Number(this.cropOptionsImgInfo.originalHeight);
- if(this.cropOptions.fixed){ // 锁定比例
- this.virtualWidth = Math.round(this.virtualHeight * scale);
- }
- let cropPosition = this.$refs.cropper.getCropAxis();
- let c_w = cropPosition.x2 - cropPosition.x1;
- let c_h = cropPosition.y2 - cropPosition.y1;
-
- let w = document.getElementsByClassName('crop-info')[0].innerText.split(' × ')[0];
- let h = document.getElementsByClassName('crop-info')[0].innerText.split(' × ')[1];
- let c_scale = w / c_w;
-
- this.$refs.cropper.goAutoCrop();
- this.$nextTick(() => {
- this.cropOptions.autoCropWidth = this.virtualWidth / c_scale;
- this.cropOptions.autoCropHeight = this.virtualHeight / c_scale;
- });
- },
- cropChange(e){
- if(e == 2 && this.cropOptions.fixed){
- this.cropOptions.fixedValue = 'original';
- this.fixedChange('original');
- }
- },
- // 预览
- previewImg(){
- this.cropimgShow = true;
- },
- // 裁剪图片
- cropImg(){
- this.mergeLoading = this.$loading({
- lock: true,
- text: '图片处理中,请稍后...',
- spinner: 'el-icon-loading',
- background: 'rgba(0, 0, 0, 0.7)'
- });
- for(let index = 0; index < this.cropList.length; index++){
- let item = this.cropList[index];
-
- let imgType = item.type;
- let suffix = item.name.lastIndexOf('.') != -1 ? item.name.substr(item.name.lastIndexOf('.')+1) : imgType.toLowerCase();
- let newPath = this.downloadDir + separator + pjson.softInfo.softName + separator + item.name.slice(0, item.name.lastIndexOf('.')) + '.' +suffix;
-
- let str;
- if(item.cropPosition && item.cropPosition.cropWidth){
- str = item.cropPosition.cropWidth + 'x' + item.cropPosition.cropHeight + '+' + item.cropPosition.cropX + '+' + item.cropPosition.cropY;
- }else{
- str = item.width + 'x' + item.height + '+' + 0 + '+' + 0;
- }
-
- let resize = [];
- if(item.cropOptions && item.cropOptions.cropType == '2' && item.cropOptions.cropClassify != '1'){
- let oWidth = item.cropOptions.fixedNumber[0];
- let oHeight = item.cropOptions.fixedNumber[1];
- resize = ['-resize', `${Number(oWidth)}x${Number(oHeight)}!`,];
- }
-
- let params = [
- 'convert.exe',
- '-crop',
- str,
- ...resize,
- item.path,
- newPath
- ];
- electronApi.spawnExec(params).then(res => {
- let imgInfo = {};
- if(item.cropPosition && item.cropPosition.cropWidth){
- imgInfo.width = item.cropPosition.cropWidth;
- }else{
- imgInfo.width = item.width;
- }
- this.addWatermark(index, imgInfo, newPath);
- }).catch(err => {
- this.mergeLoading.close();
- // errorIndex = index;
- this.$notify.error({
- title: '第【'+Number(index+1)+'】张图片出错',
- message: '请调整后重试!' + err.stderr.toString()
- });
- });
-
- }
-
- setTimeout(() => { // 延迟打开
- this.mergeLoading.close();
- electronApi.call('showItemInfolder',[this.downloadDir + separator + pjson.softInfo.softName + separator +'1.tty'])
- }, 3000);
-
- },
-
- handleDownload(data, path){
- var dataBuffer = new Buffer(data.split(',')[1], 'base64');
- fs.writeFileSync(path, dataBuffer, {'flag':'w'});
- },
- // 加载拖拽监听事件
- initDrop(){
- const dragWrapper = document.getElementById("drag-jimp");
- let domArr = [dragWrapper];
- domArr.map(item => {
- //添加拖拽事件监听器
- item.addEventListener("drop", (e) => {
- //阻止默认行为
- e.preventDefault();
- //获取文件列表
- let files = e.dataTransfer.files;
- let pathArr = [];
- for(let i = 0; i < files.length; i++){
- pathArr.push(files[i].path);
- }
- this.pushFileToList(pathArr);
- })
- //阻止拖拽结束事件默认行为
- item.addEventListener("dragover", (e) => {
- e.preventDefault();
- })
- })
- },
- cancelLoad(){
- this.cancelLoadStatus = true;
- },
- openVip(){
- this.$refs.headerRef.openVip();
- },
- updateSoft() {
- this.$refs.updateRef.updateSoft();
- },
- // 打开自定义下载目录
- openFolder(){
- let path = this.downloadDir;
- if(fs.existsSync(this.downloadDir + separator + pjson.softInfo.softName)){
- path = this.downloadDir + separator + pjson.softInfo.softName;
- } else {
- fs.mkdirSync(this.downloadDir + separator + pjson.softInfo.softName);
- path = this.downloadDir + separator + pjson.softInfo.softName;
- }
- electronApi.call('showItemInfolder',[path+'\\tty.tty'])
- },
- // 清除列表
- clearList() {
- if(this.menuIndex != 8 && this.menuIndex != 10){
- this.imgList = [];
- this.imgSrc = '';
- this.setDefaultData();
- }else if(this.menuIndex == 8){
- this.mergeList = [];
- }else{
- this.cropList = [];
- this.cropImgIndex = -1;
- this.setDefaultCropData();
- this.cropOptionsImgInfo = {};
- }
-
- this.rollFlag = false;
- this.isGif = false;
- this.gifChecked = false;
- },
- setMenuIndex(index){
- this.menuIndex = index;
- this.setDefaultData();
- if(index == 5){
- this.handleData.fonts = this.defaultFont.toString();
- }else if(index == 3){
- this.handleData.width = this.imgInfo.width ? this.imgInfo.width : 0;
- this.handleData.height = this.imgInfo.height ? this.imgInfo.height : 0;
- }else if(index == 7){
- this.setChange();
- }
- if(this.imgList.length > 0){
- this.setDefaultImgInfo(this.imgList[0]);
- }
-
- if([3,4,5,6,9].indexOf(this.menuIndex) == -1){ // 滚动事件
- this.rollFlag = false;
- }
-
- },
- setDefaultCropData(){
- this.cropOptions = {
- img: '',
- autoCrop: true, // 是否默认生成截图框
- autoCropWidth: 100,
- autoCropHeight: 100,
- cropWidth: 100,
- cropHeight: 100,
- original: false,
- maxImgSize: 20000,
- canMove: false,
- centerBox: true, // 截图框是否被限制在图片里面
- fixed: false, //是否开启截图框宽高固定比例
- fixedValue: 'free',
- cropType: '1',
- cropClassify: '1',
- fixedNumber: [1, 1],
- infoTrue: true,
- previewInfo: '',
- cropScale: 100,
- };
- },
- setDefaultData(){
- this.handleData = {
- dpi: 300,
- width: 0,
- height: 0,
- pathType: this.handleData.pathType, // 输出目录类型
- newPath: this.handleData.newPath, // 新路径
- autoRename: false, // 是否自动重命名
- imgFormat: 'JPG', // 转换类型
- quality: 92, // 图片品质
- colorNum: 256, // 颜色数量
- color: '0', // 图片色彩
- sizeType: '1', // 调整尺寸
- scaling: 100, // 缩放比例
- colorValue: 256,
- paintValue: 1, // 油画数值
- brightnessValue: 0, // 亮度
- saturationValue: 0, //饱和度
- hueValue: 0, // 色调
- contrastValue: 0, // 对比度
- rotateValue: 0, // 旋转角度
- opacityValue: 100, // 透明度
- compressScaling:100,
- compressOutType:2,
- watermarkType: '1', // 水印类型 1文字 2图片
- watermarkStyle: '1', // 1 单个 2平铺
- watermarkValue: '', // 水印文字内容
- watermarkColor: '#ff0000',
- watermarkFont: 16,
- watermarkX: 0,
- watermarkY: 0,
- watermarkDensityX: 3, // 平铺水印密度
- watermarkDensityY: 3, // 平铺水印密度
- watermarkImgPath: '', //图片水印路径
- watermarkImgOpactiy: 100, // 水印不透明度
- watermarkImgSize: 100, //水印缩放比例
- watermarkImgRotate:0,
- watermarkPosition: 'Center',
- lineFlag: false,
- lineWidth: 3,
- lineColor: '#ff0000',
- fonts: this.defaultFont.toString(),
- rotate: 30,
- circularFlag: false,
- circularValue: 10,
- hflip: false,
- vflip: false,
- lockScale: true,
- };
- },
- // 选择水印图片
- getImgPath(e) {
- if (e) {
- this.handleData.watermarkImgPath = e.path;
- this.handleImg();
- }
- },
- pickFile(){
- electronApi.call('pickFile', [this.imgFormat.join(','),true]).then(async(files) =>{
- this.pushFileToList(files,0);
- });
- },
- pickDir(){
- electronApi.call('pickDir', []).then((path) =>{
- this.dealDir(path);
- });
- },
- dealDir(currentDirPath){
- let files = fs.readdirSync(currentDirPath)
- for (let i = 0; i < files.length; i++) {
- let name = files[i];
- var filePath = pathMod.join(currentDirPath, name);
- var stat = fs.statSync(filePath);
- if (stat.isFile()) {
- this.pushFileToList([filePath]);
- } else if (stat.isDirectory()) {
- this.dealDir(filePath)
- }
- }
- },
- pushFileToList(files){
- // 直接渲染
- files.map(file => {
- let filename = file.substr(file.lastIndexOf(separator)+1);
-
- let size = fs.statSync(file).size;
- let imgInfo = {
- name: filename,
- size: this.$utils.handleSize(size),
- width: 0,
- height: 0,
- originalWidth: 0,
- originalHeight: 0,
- path: file,
- type: filename.lastIndexOf('.') == -1 ? '' : filename.substr(filename.lastIndexOf('.')+1),
- loadPercent: 0,
- percent: 0,
- top: 0,
- left: 0
- };
-
- if(!imgInfo.type){
- this.$message({message: '不是有效的图片文件! - '+ file , type: 'warning'});
- }else{
- if(this.imgFormat.indexOf(imgInfo.type.toUpperCase()) == -1){
- this.$message({message: '不是有效的图片文件! - '+ file , type: 'warning'});
- }else{
- if(imgInfo.type.toUpperCase() == 'GIF'){
- this.isGif = true;
- }
- try {
- let dimensions = sizeOf(file);
- imgInfo.width = dimensions.width;
- imgInfo.height = dimensions.height;
- imgInfo.originalWidth = dimensions.width;
- imgInfo.originalHeight = dimensions.height;
- } catch (error) {
- }
-
- // 过滤重复图片
- let flag = true;
- if(this.menuIndex != 8 && this.menuIndex != 10) {
- for(let m = 0; m < this.imgList.length; m++){
- if(this.imgList[m].name == imgInfo.name && this.imgList[m].path == imgInfo.path){
- flag = false;
- break;
- }
- }
- }else if(this.menuIndex == 8){
- for(let m = 0; m < this.mergeList.length; m++){
- if(this.mergeList[m].name == imgInfo.name && this.mergeList[m].path == imgInfo.path){
- flag = false;
- break;
- }
- }
- }else{
- for(let m = 0; m < this.cropList.length; m++){
- if(this.cropList[m].name == imgInfo.name && this.cropList[m].path == imgInfo.path){
- flag = false;
- break;
- }
- }
- }
-
- if(!flag){
- this.$message({message: '该图片已经存在队列中 - '+ file , type: 'warning'});
- }else{
- if(this.menuIndex != 8 && this.menuIndex != 10){
- this.imgList.push(imgInfo);
- }else if(this.menuIndex == 8){
- if(this.mergeList.length < 100){
- this.mergeList.push(imgInfo);
- this.sortChange(this.mergeData.sortType);
- }
- }else{
- this.cropList.push(imgInfo);
- if(this.cropList.length == 1){
- this.selectCropImg(0);
- }
- }
- }
- }
- }
- })
- // 设置第一个为默认图片
- if(this.imgSrc == '' && this.imgList[0]){
- this.setDefaultImgInfo(this.imgList[0])
- }
-
- if(this.menuIndex == 7){ // 重命名
- this.setChange();
- }
-
- },
- // 设置默认的图片
- setDefaultImgInfo(info){
- this.imgInfo = info;
- this.handleData.width = this.imgInfo.width;
- this.handleData.height = this.imgInfo.height;
- this.imgLoading = true;
-
- if([1,2,7,11].indexOf(this.menuIndex) == -1){
- electronApi.fileStream(this.imgInfo.path).then(buffer => {
- this.imgSrc = "data:image/png;base64,"+buffer.toString('base64');
- this.imgLoading = false;
- }).catch(err => {
- this.imgLoading = false;
- })
- }
-
- if([3,4,5,6,9].indexOf(this.menuIndex) > -1){ // 绑定滚动事件
- setTimeout(() => {
- if(!this.rollFlag){
- this.initRoll();
- }
- }, 600);
- }
-
- },
- // 选择新路径
- getFolder(e) {
- this.handleData.newPath = e.path;
- this.downloadDir = e.path;
- },
- selectTab(data, index) {
- let currentRow = data.rowIndex > -1 ? this.imgList[data.rowIndex] : data;
- index = index ? 0 : data.rowIndex;
- this.imgInfo = currentRow;
- this.imgInfoIndex = index;
-
- if([3,6,7,9].indexOf(this.menuIndex) > -1){
- this.imgLoading = true;
- electronApi.fileStream(currentRow.path).then(buffer => {
- this.imgSrc = "data:image/png;base64,"+buffer.toString('base64');
- this.imgLoading = false;
- }).catch(err => {
- this.imgLoading = false;
- })
- this.handleData.width = Number(currentRow.width);
- this.handleData.height = Number(currentRow.height);
- }else if([4,5].indexOf(this.menuIndex) > -1){
- this.handleImg();
- }else if(this.menuIndex == 1){
- this.handleData.imgFormat = 'JPG';
- }
- },
- // 导出
- async exportImg(flag) {
- let authority = this.$refs.headerRef.authority;
- if(!fs.existsSync(this.downloadDir + separator + pjson.softInfo.softName)){
- fs.mkdirSync(this.downloadDir + separator + pjson.softInfo.softName);
- }
- // 图片拼接
- if(this.menuIndex == 8 && this.mergeList.length > 0){
- if (!authority.isAuthority && !flag) {
- this.$refs.headerRef.memberModel = true;
- this.$refs.headerRef.isClick = true;
- return false;
- } else {
- this.$refs.headerRef.memberModel = false;
- }
- this.loading = true;
- setTimeout(()=>{
- this.loading = false;
- }, 1500)
-
- if(this.mergeData.sortType != 3){
- this.exportMerge2();
- }else{
- this.exportMerge();
- }
- }
-
- // 图片裁剪
- if(this.menuIndex == 10 && this.cropList.length > 0){
- if (!authority.isAuthority && !flag) {
- this.$refs.headerRef.memberModel = true;
- this.$refs.headerRef.isClick = true;
- return false;
- } else {
- this.$refs.headerRef.memberModel = false;
- }
- this.loading = true;
- setTimeout(()=>{
- this.loading = false;
- }, 1500)
-
- this.cropImg();
- }
-
- if (this.imgList.length > 0 && this.menuIndex != 8 && this.menuIndex != 10) {
- if (!authority.isAuthority && !flag) {
- this.$refs.headerRef.memberModel = true;
- this.$refs.headerRef.isClick = true;
- return false;
- } else {
- this.$refs.headerRef.memberModel = false;
- }
-
- this.loading = true;
- setTimeout(()=>{
- this.loading = false;
- }, 1500)
-
- if(this.menuIndex == 7){ // 重命名
- this.exportRename();
- return false;
- }
-
- // 删除水印,防止直接篡改水印图片
- this.deleteSysWtater();
-
- // 更改尺寸的时候,宽度和高度不允许为0
- if(this.menuIndex == 3 && this.handleData.sizeType != 1){
- if(this.handleData.width <= 0 || this.handleData.height <=0){
- this.$message({message: '请设置缩放的宽度和高度' , type: 'warning'});
- return false
- }
- }
-
- //percent
- let taskArr = [];
- let newPath = '';
- for(let i=0; i<this.imgList.length; i++){
- let item = this.imgList[i];
- let lastIndex = item.path.lastIndexOf('.');
- let imgType = item.type;
- let suffix = '';
- if(this.menuIndex == 1){
- suffix = this.handleData.imgFormat.toLowerCase();
- }else{
- suffix = item.name.lastIndexOf('.') != -1 ? item.name.substr(item.name.lastIndexOf('.')+1) : imgType.toLowerCase();
- }
- // 图片压缩,输出格式为jpg
- if(this.menuIndex == 2 && this.handleData.compressOutType == 1){
- suffix = 'jpg';
- }
- newPath = this.downloadDir + separator + pjson.softInfo.softName + separator + item.name.slice(0, item.name.lastIndexOf('.')) + '.' +suffix;
-
- // 处理图像
- let task = this.dealImg(i, item, newPath);
- if(task){
- taskArr.push(task);
- }
-
- if((i+1) % this.execLimit == 0){
- await Promise.all(taskArr).then(result => {
- taskArr = [];
- }).catch(err => {
- })
- }
- }
-
- if(taskArr.length > 0){
- await Promise.all(taskArr).then(result => {
- taskArr = [];
- }).catch(err => {
- // 错误文件添加到服务中
- console.log('err',err);
- })
- }
-
- // 打开文件夹
- if(this.imgList.length > 0){
- this.$message({message: '恭喜你,任务已完成!', type: 'success'});
- electronApi.call('showItemInfolder',[newPath])
- }
- }
- },
- // 操作
- handleImg() {
- if (this.imgInfo.path) {
- this.imgLoading = true;
- this.dealImg(this.imgInfoIndex);
- }
- },
- // 处理图片
- dealImg(index, img, path){
- let reduceFlag = img ? false : true;
- let imgInfo = img ? img : this.imgInfo;
- let newPath = img ? path : this.previewTmpPath;
- let task = '';
- switch (this.menuIndex) {
- case 11: // 修改dpi
- task = new Promise((resolve,reject) => {
- let imgPath = imgInfo.path;
- let cmd = [
- 'convert.exe',
- '-monitor',
- imgPath,
- '-density',
- this.handleData.dpi,
- '-units',
- 'PixelsPerInch',
- newPath
- ];
-
- electronApi.spawnExec(cmd,{
- stderr:(data) => {
- let str = data.toString();
- const regexDuration = /Load.*?,(.*?)%/;
- const regexDuration2 = /Save.*?,(.*?)%/;
-
- const res = regexDuration.exec(str);
- const res2 = regexDuration2.exec(str);
-
- let p1 = 0;
- let p2 = 0;
- if(res && res[1]){
- p1 = parseInt(res[1]);
- if(p1 > 0){
- imgInfo.percent = Math.round(p1/2);
- }
- }else{
- if(res2 && res2[1]){
- p2 = parseInt(res2[1]);
- }
- if(p2 > 0){
- imgInfo.percent = Math.round(50+(p2/2));
- }
- }
-
- if(this.imgList.indexOf(index)){
- this.imgList.splice(index,1,imgInfo);
- }
- }
- }).then(res => {
- setTimeout(() => {
- if(this.imgList.indexOf(index)){
- imgInfo.percent = 100;
- this.imgList.splice(index, 1, imgInfo);
- }else{
- reject({type:this.menuIndex,index,err:'用户强制终止!'});
- }
- }, 150)
-
- //未购买 添加系统水印
- this.addWatermark(index,imgInfo,newPath);
- resolve({type:this.menuIndex,index, img});
- }).catch(err => {
- // console.log(err.stderr.toString());
- reject({type:this.menuIndex,index,err});
- });
- });
-
- break;
- case 1: // 格式转换
- task = new Promise((resolve,reject) => {
-
- let imgPath = imgInfo.path;
- let gifParams = [];
- if(imgInfo.type.toLowerCase() == 'psd'){
- imgPath = imgInfo.path + '[0]';
- }
- if(imgInfo.type.toLowerCase() == 'gif'){
- if(this.gifChecked){
- gifParams = ['-coalesce'];
- let name = imgInfo.name.slice(0, imgInfo.name.lastIndexOf('.'));
- let gifPath = this.downloadDir + separator + pjson.softInfo.softName + separator + name;
- if(!fs.existsSync(gifPath)){
- fs.mkdirSync(gifPath);
- }
- newPath = gifPath + separator + name + '.' + this.handleData.imgFormat.toLowerCase();
- }else{
- imgPath = imgInfo.path + '[0]';
- }
- }
- let cmd = [
- 'convert.exe',
- '-monitor',
- ...gifParams,
- imgPath,
- newPath
- ];
-
- electronApi.spawnExec(cmd,{
- stderr:(data) => {
- let str = data.toString();
- const regexDuration = /Load.*?,(.*?)%/;
- let regexDuration2 = /Save.*?,(.*?)%/;
- if(imgInfo.type.toLowerCase() == 'gif'){
- regexDuration2 = /Write.*?,(.*?)%/;
- }
-
- const res = regexDuration.exec(str);
- const res2 = regexDuration2.exec(str);
- let p1 = 0;
- let p2 = 0;
- if(res && res[1]){
- p1 = parseInt(res[1]);
- if(p1 > 0){
- imgInfo.percent = Math.round(p1/2);
- }
- }else{
- if(res2 && res2[1]){
- p2 = parseInt(res2[1]);
- }
- if(p2 > 0){
- imgInfo.percent = Math.round(50+(p2/2));
- }
- }
-
- if(this.imgList.indexOf(index)){
- this.imgList.splice(index,1,imgInfo);
- }
- }
- }).then(res => {
- setTimeout(() => {
- if(this.imgList.indexOf(index)){
- imgInfo.percent = 100;
- this.imgList.splice(index, 1, imgInfo);
- }else{
- reject({type:this.menuIndex,index,err:'用户强制终止!'});
- }
- }, 150)
- //未购买 添加系统水印
- this.addWatermark(index,imgInfo,newPath);
- resolve({type:this.menuIndex,index, img});
- }).catch(err => {
- // console.log(err.stderr.toString());
- reject({type:this.menuIndex,index,err});
- });
- });
-
- break;
-
- case 2: // 图片压缩
- task = new Promise(async (resolve,reject) => {
- let extraParams = [];
- if(this.handleData.compressOutType == 1 || imgInfo.type.toLowerCase() != 'png'){
- if(this.handleData.compressOutType == 1 || imgInfo.type.toLowerCase() == 'jpg' || imgInfo.type.toLowerCase() == 'JPEG'){
- let sizeOld = fs.statSync(imgInfo.path).size;
-
- extraParams=['-resize',this.handleData.compressScaling+'%','-define','jpeg:dct-method=fastest','-define','jpeg:extent='+sizeOld,'-sampling-factor','4:2:0','-strip','-interlace','Plane','-background','white','-flatten','-alpha','off','-quality',this.handleData.quality+'%']
- }else{
- extraParams=['+dither','-strip','-colors',256*(this.handleData.quality/90),'-depth',8]
- }
-
- electronApi.spawnExec(['convert.exe','-monitor',...extraParams,imgInfo.path, newPath],{
- stderr:(data) => {
- let str = data.toString();
- const regexDuration = /Load.*?,(.*?)%/;
- const regexDuration2 = /Save.*?,(.*?)%/;
- const res = regexDuration.exec(str);
- const res2 = regexDuration2.exec(str);
- let p1 = 0;
- let p2 = 0;
- if(res && res[1]){
- p1 = parseInt(res[1]);
- if(p1 > 0){
- imgInfo.percent = Math.round(p1/2);
- }
- }else{
- if(res2 && res2[1]){
- p2 = parseInt(res2[1]);
- }
- if(p2 > 0){
- imgInfo.percent = Math.round(50+(p2/2));
- }
- }
-
- if(this.imgList[index]){
- this.imgList.splice(index,1,imgInfo);
- }
- }
- }).then(res => {
- setTimeout(() => {
- if(this.imgList[index]){
- imgInfo.percent = 100;
- this.imgList.splice(index, 1, imgInfo);
- }else{
- reject({type:this.menuIndex,index,err:'用户强制终止!'});
- }
- }, 150)
- //未购买 添加系统水印
- this.addWatermark(index,imgInfo,newPath);
- resolve({type:this.menuIndex,index, imgInfo});
- }).catch(err => {
- err.stdout = err.stdout.toString();
- err.stderr = err.stderr.toString();
-
- reject({type:this.menuIndex,index,err});
- });
- }else{
- // 复制文件到缓存目录 生成结束后输出到目标文件夹
- let tmpPath = os.tmpdir()+separator+'YSI_'+Math.random();
- let tmpPath2 = os.tmpdir()+separator+'YSO_'+Math.random() + '.png';
-
- fs.copyFileSync(imgInfo.path,tmpPath);
- // 添加系统水印
- await this.addWatermark(index,imgInfo,tmpPath);
- electronApi.spawnExec(['pngquant.exe',tmpPath,'-f','-v','--strip','--quality',this.handleData.quality,'-o',tmpPath2],{
- stderr:(data) => {
- let str = data.toString();
- const regexDuration = /selecting colors...(.*?)%/;
- const res = regexDuration.exec(str);
- if(res && res[1]){
- imgInfo.percent = Math.round(parseInt(res[1])-2);
- }
- if(this.imgList[index]){
- this.imgList.splice(index,1,imgInfo);
- }
- }
- }).then((res) => {
- setTimeout(() => {
- if(this.imgList[index]){
- imgInfo.percent = 100;
- this.imgList.splice(index, 1, imgInfo);
- }else{
- reject({type:this.menuIndex,index,err:'用户强制终止!'});
- }
- }, 150)
- // 复制
- fs.copyFileSync(tmpPath2,newPath);
- resolve({type:this.menuIndex,index, imgInfo});
- }).catch(err => {
- err.stdout = err.stdout.toString();
- err.stderr = err.stderr.toString();
-
- // 如果失败,重新使用推荐的最小值来转换
- // const regexQ = /\(Q=(.*?)\)/g;
- // const res2 = regexQ.exec(err.stderr);
- // const quality = res2[1];
- this.pngFailedExec(index,tmpPath,tmpPath2,imgInfo,newPath).then(rr => {
- resolve({type:this.menuIndex,index, imgInfo});
- }).catch(err2 => {
- reject({type:this.menuIndex,index,err});
- });
- });
- }
- });
- break;
- case 3: // 更改尺寸
- case 9: // 批量旋转
- task = new Promise((resolve,reject) => {
- let params = [];
- let extraParams = [];
- if(this.handleData.rotateValue != 0){
- extraParams = ['-rotate',this.handleData.rotateValue];
- }
-
- let vflipParams = [];
- let hflipParams = [];
- if(this.handleData.vflip){
- vflipParams = ['-flip'];
- }
- if(this.handleData.hflip){
- hflipParams = ['-flop'];
- }
- if (this.handleData.sizeType == 1) { // 按照比列缩放
- params = [
- 'convert.exe',
- '-monitor',
- '-resize',
- this.handleData.scaling+'%',
- ...extraParams,
- ...vflipParams,
- ...hflipParams,
- imgInfo.path,
- newPath
- ];
- } else { // 按照尺寸缩放
- params = [
- 'convert.exe',
- '-monitor',
- '-resize',
- `${Number(this.handleData.width)}x${Number(this.handleData.height)}!`,
- ...extraParams,
- ...vflipParams,
- ...hflipParams,
- imgInfo.path,
- newPath
- ];
- }
- electronApi.spawnExec(params,{
- stderr:(data) => {
- let str = data.toString();
- const regexDuration = /Load.*?,(.*?)%/;
- const regexDuration2 = /Save.*?,(.*?)%/;
-
- const res = regexDuration.exec(str);
- const res2 = regexDuration2.exec(str);
- let p1 = 0;
- let p2 = 0;
- if(res && res[1]){
- p1 = parseInt(res[1]);
- if(p1 > 0){
- imgInfo.percent = Math.round(p1/2);
- }
- }else{
- if(res2 && res2[1]){
- p2 = parseInt(res2[1]);
- }
- if(p2 > 0){
- imgInfo.percent = Math.round(50+(p2/2));
- }
- }
-
- if(this.imgList[index]){
- this.imgList.splice(index,1,imgInfo);
- }
- }
- }).then(res => {
- setTimeout(() => {
- if(this.imgList[index]){
- imgInfo.percent = 100;
- this.imgList.splice(index, 1, imgInfo);
- }else{
- reject({type:this.menuIndex,index,err:'用户强制终止!'});
- }
- }, 150)
- //未购买 添加系统水印
- this.addWatermark(index,imgInfo,newPath);
-
- resolve({type:this.menuIndex,index, img});
- }).catch(err => {
- reject({type:this.menuIndex,index,err});
- });
- })
-
- break;
- case 4: // 美化图片
- task = new Promise((resolve,reject) => {
- let extraParams2 = [];
- let extraParams3 = [];
- let reduceParams = [];
- switch (this.handleData.color){
- case '1': // 黑白
- extraParams2 = ['-type', 'bilevel'];
- break;
- case '2': // 灰色
- extraParams2 = ['-type','grayscale'];
- break;
- case '3': // 反转
- extraParams2 = ['-channel', 'RGB', '-negate'];
- break;
- case '4': // 油画
- extraParams2 = ['-paint', Number(this.handleData.paintValue)-1];
- break;
- }
- if(this.handleData.lineFlag){
- extraParams3 = ['-bordercolor',this.handleData.lineColor,'-border',this.handleData.lineWidth];
- }
-
- if(reduceFlag){ // 缩小尺寸实现快速渲染???
- //reduceParams = ['-resize','10%'];
- }
- let params2 = [
- 'convert.exe',
- imgInfo.path,
- '-monitor',
- ...reduceParams,
- '-colors',
- this.handleData.colorValue,
- '-brightness-contrast',
- `${Number(this.handleData.brightnessValue)}/${Number(this.handleData.contrastValue)}`,
- '-modulate',
- '100,'+ Number(this.handleData.saturationValue+100) + ',' + Number(this.handleData.hueValue+100),
- '-alpha', 'set', '-channel', 'A', '-evaluate', 'Multiply', this.handleData.opacityValue/100, '+channel',
- ...extraParams2,
- ...extraParams3,
- newPath
- ];
- electronApi.spawnExec(params2,{
- stderr:(data) => {
- let str = data.toString();
- const regexDuration = /Function.*?,(.*?)%/;
- const regexDuration2 = /save.*?,(.*?)%/;
-
- const res = regexDuration.exec(str);
- const res2 = regexDuration2.exec(str);
- let p1 = 0;
- let p2 = 0;
- if(res && res[1]){
- p1 = parseInt(res[1]);
- if(p1 > 0){
- imgInfo.percent = Math.round(p1/2);
- }
- }else{
- if(res2 && res2[1]){
- p2 = parseInt(res2[1]);
- }
- if(p2 > 0){
- imgInfo.percent = Math.round(50+(p2/2));
- }
- }
-
- if(this.imgList[index]){
- this.imgList.splice(index,1,imgInfo);
- }
- }
- }).then(res => {
- setTimeout(() => {
- if(this.imgList[index]){
- imgInfo.percent = 100;
- this.imgList.splice(index, 1, imgInfo);
- }else{
- reject({type:this.menuIndex,index,err:'用户强制终止!'});
- }
- }, 150)
- if(!img){ // 预览状态
- electronApi.fileStream(newPath).then(buffer => {
- this.imgSrc = "data:image/png;base64,"+buffer.toString('base64');
- this.imgLoading = false;
- })
- }
-
- //未购买 添加系统水印
- this.addWatermark(index,imgInfo,newPath);
- resolve({type:this.menuIndex, index, img});
- }).catch(err => {
- reject({type:this.menuIndex, index,err});
- });
- });
- break;
- case 5: // 添加水印
- if (this.handleData.watermarkType == '1') { // 文字水印
- if(this.handleData.fonts == ''){
- this.$message({message: '请选择字体', type: 'warning'});
- this.imgLoading = false;
- break;
- }else{
- task = this.textWatermark(index, imgInfo, newPath,!img);
- }
- } else if (this.handleData.watermarkType == '2') { // 图片水印
- // 平铺功能去掉
- this.handleData.watermarkStyle = 1;
- if(!this.handleData.watermarkImgPath){
- this.$message({message: '请上传图片水印', type: 'warning'});
- this.imgLoading = false;
- break;
- }else{
- task = this.imgWatermark(index, imgInfo, newPath,!img);
- }
- }
- break;
-
- case 6: // 圆角设置
- task = new Promise((resolve,reject) => {
- let cirPath = newPath;
- if(this.handleData.circularValue > 0){
- cirPath = newPath.substr(0, newPath.lastIndexOf('.')+1) + 'png';
- }
- let extraParams = ['-draw', 'roundrectangle 0,0,'+imgInfo.width+','+imgInfo.height+','+imgInfo.width*this.handleData.circularValue/100+','+imgInfo.width*this.handleData.circularValue/100]
- let params2 = [
- 'convert.exe',
- '-size',
- imgInfo.width+'x'+imgInfo.height,
- 'xc:none',
- '-fill',
- imgInfo.path,
- '-monitor',
- ...extraParams,
- cirPath
- ];
-
- electronApi.spawnExec(params2,{
- stderr:(data) => {
- let str = data.toString();
- const regexDuration = /Function.*?,(.*?)%/;
- const regexDuration2 = /save.*?,(.*?)%/;
-
- const res = regexDuration.exec(str);
- const res2 = regexDuration2.exec(str);
-
- let p1 = 0;
- let p2 = 0;
- if(res && res[1]){
- p1 = parseInt(res[1]);
- if(p1 > 0){
- imgInfo.percent = Math.round(p1/2);
- }
- }else{
- if(res2 && res2[1]){
- p2 = parseInt(res2[1]);
- }
- if(p2 > 0){
- imgInfo.percent = Math.round(50+(p2/2));
- }
- }
-
- if(this.imgList[index]){
- this.imgList.splice(index,1,imgInfo);
- }
- }
- }).then(res => {
- setTimeout(() => {
- if(this.imgList[index]){
- imgInfo.percent = 100;
- this.imgList.splice(index, 1, imgInfo);
- }else{
- reject({type:this.menuIndex,index,err:'用户强制终止!'});
- }
- }, 150)
-
- if(!img){ // 预览状态
- electronApi.fileStream(cirPath).then(buffer => {
- this.imgSrc = "data:image/png;base64,"+buffer.toString('base64');
- this.imgLoading = false;
- })
- }
-
- //未购买 添加系统水印
- this.addWatermark(index,imgInfo,cirPath);
- resolve({type:this.menuIndex, index, img});
- }).catch(err => {
- reject({type:this.menuIndex, index,err});
- });
- });
- break;
- }
- return task;
- },
- //如果转换失败,则使用推荐的Quaity转换图片
- pngFailedExec(index,tmpPath,tmpPath2,imgInfo,newPath){
- return new Promise((resolve,reject) => {
- electronApi.spawnExec(['pngquant.exe',tmpPath,'-f','-v','--strip','-o',tmpPath2],{
- stderr:(data) => {
- let str = data.toString();
- const regexDuration = /selecting colors...(.*?)%/;
- const res = regexDuration.exec(str);
- if(res && res[1]){
- imgInfo.percent = Math.round(parseInt(res[1])-2);
- }
- if(this.imgList[index]){
- this.imgList.splice(index,1,imgInfo);
- }
- }
- }).then((res) => {
- setTimeout(() => {
- if(this.imgList[index]){
- imgInfo.percent = 100;
- this.imgList.splice(index, 1, imgInfo);
- }else{
- reject({type:this.menuIndex,index,err:'用户强制终止!'});
- }
- }, 150)
- // 复制
- fs.copyFileSync(tmpPath2,newPath);
- resolve({type:this.menuIndex,index, imgInfo});
- }).catch(err => {
- err.stdout = err.stdout && err.stdout.toString();
- err.stderr = err.stderr && err.stderr.toString();
-
- reject({type:this.menuIndex,index,err});
- });
- });
- },
-
- // scaleWidthChange
- scaleWidthChange(e){
- let scale = Number(this.imgInfo.originalWidth) / Number(this.imgInfo.originalHeight);
- if(this.handleData.lockScale){ // 锁定比例
- this.handleData.height = Math.round(this.handleData.width / scale);
- }
- },
- // scaleHeightChange
- scaleHeightChange(e){
- let scale = Number(this.imgInfo.originalWidth) / Number(this.imgInfo.originalHeight);
- if(this.handleData.lockScale){ // 锁定比例
- this.handleData.width = Math.round(this.handleData.height * scale);
- }
- },
- // 文字水印
- async textWatermark(index, imgInfo, newPath,isPreview=false) {
- let m = this.handleData.watermarkDensityX <= 0 ? 3 : this.handleData.watermarkDensityX;
- let n = this.handleData.watermarkDensityY <= 0 ? 3 : this.handleData.watermarkDensityY;
-
- return new Promise((resolve,reject) => {
- let tmpPath = os.tmpdir()+separator+'water_font_'+Math.random()+'.png';
- let params = [
- 'convert.exe',
- '-monitor',
- '-background',
- 'none',
- '-fill',
- this.handleData.watermarkColor,
- '-font',
- this.handleData.fonts.toString(),
- '-pointsize',
- this.handleData.watermarkFont,
- '-alpha', 'set', '-channel', 'A', '-evaluate', 'Multiply', this.handleData.watermarkImgOpactiy/100, '+channel', // 透明度
- '-rotate',
- this.handleData.rotate,
- 'label:' + (this.handleData.watermarkValue ? this.handleData.watermarkValue : pjson.softInfo.softName),
- '-gravity',
- 'center',
- '-extent',
- this.handleData.watermarkStyle == 2 ? (imgInfo.width/m)+'x'+(imgInfo.height/n) : '100%',
- tmpPath
- ];
- electronApi.spawnExec(params,{stderr:(data) => { imgInfo.percent = 30;this.imgList.splice(index,1,imgInfo);}}).then(async (res) => {
- // 生成平铺水印图片
- if(this.handleData.watermarkStyle == 2){ // 平铺
- let tmpPath2 = os.tmpdir()+separator+'water_pu_'+Math.random()+'.png';
- let params2 = [
- 'convert.exe',
- '-monitor',
- tmpPath,
- '-write',
- 'mpr:tiler',
- '+delete',
- '-size',
- imgInfo.width+'x'+imgInfo.height,
- 'tile:mpr:tiler',
- tmpPath2
- ];
- await electronApi.spawnExec(params2,{stderr:(data) => { imgInfo.percent=60;this.imgList.splice(index,1,imgInfo);}}).then(async (res2) => {
- await this.waterComposite(index, imgInfo, newPath, tmpPath2);
- if(fs.existsSync(tmpPath)){
- fs.unlinkSync(tmpPath);
- }
- })
- }else{
- await this.waterComposite(index, imgInfo, newPath, tmpPath);
- }
-
- if(isPreview){ // 预览状态
- electronApi.fileStream(newPath).then(buffer => {
- this.imgSrc = "data:image/png;base64,"+buffer.toString('base64');
- this.imgLoading = false;
- }).catch(err => {
- this.imgLoading = false;
- })
- }
- resolve({type:this.menuIndex, index:index, info:imgInfo});
- }).catch(err => {
- reject({type:this.menuIndex, index:index, err: err});
- });
- });
- },
- // 图片水印
- async imgWatermark(index, imgInfo, newPath,isPreview=false) {
- let m = this.handleData.watermarkDensityX <= 0 ? 3 : this.handleData.watermarkDensityX;
- let n = this.handleData.watermarkDensityY <= 0 ? 3 : this.handleData.watermarkDensityY;
- return new Promise((resolve,reject) => {
- let tmpPath = os.tmpdir()+separator+'water_img_'+Math.random()+'.png';
-
- let params = [
- 'convert.exe',
- '-monitor',
- '-background',
- 'none',
- '-resize',
- `${Number(this.handleData.watermarkImgSize)}%`,
- '-alpha', 'set', '-channel', 'A', '-evaluate', 'Multiply', this.handleData.watermarkImgOpactiy/100, '+channel', // 透明度
- '-rotate',
- this.handleData.watermarkImgRotate,
- '-gravity',
- 'center',
- '-extent',
- this.handleData.watermarkStyle == 2 ? (imgInfo.width/m)+'x'+(imgInfo.height/n) : '100%',
- this.handleData.watermarkImgPath,
- tmpPath
- ];
- electronApi.spawnExec(params).then(async (res) => {
- // 生成平铺水印图片
- if(this.handleData.watermarkStyle == 2){ // 平铺
- let tmpPath2 = os.tmpdir()+separator+'water_pu_'+Math.random()+'.png';
- let params2 = [
- 'convert.exe',
- '-monitor',
- tmpPath,
- '-write',
- 'mpr:tiler',
- '+delete',
- '-size',
- imgInfo.width+'x'+imgInfo.height,
- 'tile:mpr:tiler',
- tmpPath2
- ];
- await electronApi.spawnExec(params2,{stderr:(data) => { imgInfo.percent=60;this.imgList.splice(index,1,imgInfo);}}).then(async (res2) => {
- await this.waterComposite(index, imgInfo, newPath, tmpPath2);
- if(fs.existsSync(tmpPath)){
- fs.unlinkSync(tmpPath);
- }
- })
- }else{
- await this.waterComposite(index, imgInfo, newPath, tmpPath);
- }
- if(isPreview){ // 预览状态
- electronApi.fileStream(newPath).then(buffer => {
- this.imgSrc = "data:image/png;base64,"+buffer.toString('base64');
- this.imgLoading = false;
- }).catch(err => {
- this.imgLoading = false;
- })
- }
- resolve({type:this.menuIndex, index:index, info:imgInfo});
- }).catch(err => {
- reject({type:this.menuIndex, index:index, err: err});
- });
- });
- },
- async waterComposite(index, imgInfo, newPath,waterImg){
- let params2 = [
- 'convert.exe',
- '-monitor',
- imgInfo.path,
- waterImg,
- '-gravity',
- this.handleData.watermarkStyle == 2 ? 'Center' : this.handleData.watermarkPosition,
- '-geometry',
- '+'+this.handleData.watermarkX+'+'+this.handleData.watermarkY,
- '-composite',
- newPath
- ];
- await electronApi.spawnExec(params2,{
- stderr:(data) => {
- let percent = 0;
- let str = data.toString();
- const regexDuration = /Load.*?,(.*?)%/;
- const regexDuration2 = /Resize.*?,(.*?)%/;
-
- const res = regexDuration.exec(str);
- const res2 = regexDuration2.exec(str);
- let p1 = 0;
- let p2 = 0;
- if(res && res[1]){
- p1 = parseInt(res[1]);
- if(p1 > 0){
- imgInfo.percent = Math.round(p1/2);
- }
- }else{
- if(res2 && res2[1]){
- p2 = parseInt(res2[1]);
- }
- if(p2 > 0){
- imgInfo.percent = Math.round(50+(p2/2));
- }
- }
-
- if(this.handleData.watermarkStyle == 2){ // 平铺
- imgInfo.percent = 60 + Math.round(percent*0.4);
- }else{
- imgInfo.percent = percent;
- }
- if(this.imgList[index]){
- this.imgList.splice(index,1,imgInfo);
- }
- },
- }).then(res2 => {
- setTimeout(() => {
- if(this.imgList[index]){
- imgInfo.percent = 100;
- this.imgList.splice(index, 1, imgInfo);
- if(fs.existsSync(waterImg)){
- fs.unlinkSync(waterImg);
- }
- }else{
- reject({type:this.menuIndex,index,err:'用户强制终止!'});
- }
- }, 150)
- //未购买 添加系统水印
- this.addWatermark(index,{...imgInfo,path:newPath},newPath);
- });
- },
- // 初始化系统水印图片
- async initSysWater(imgInfo){
- return new Promise((resolve,reject) => {
- let fontSize = 40;
- let width = imgInfo.width;
- if(this.menuIndex == 3){
- width = width * (this.handleData.scaling / 100);
- }
- if (width < 500) {
- fontSize = 16;
- } else if (width < 1000) {
- fontSize = 28
- }else if(width < 2000){
- fontSize = 40;
- }else if(width < 3000){
- fontSize = 100;
- }else{
- fontSize = 220;
- }
- let sysDefaultTmpPath = os.tmpdir()+separator+'water_xy_'+fontSize+'.png';
- let params = [
- 'convert.exe',
- '-monitor',
- '-background',
- 'none',
- '-fill',
- 'rgba(0,0,0,0.8)',
- '-font',
- this.defaultFont,
- '-pointsize',
- fontSize,
- 'label:https://www.xingyousoft.com',
- sysDefaultTmpPath
- ];
- if(fs.existsSync(sysDefaultTmpPath)){
- resolve(sysDefaultTmpPath)
- }else{
- electronApi.spawnExec(params).then((res) => {
- resolve(sysDefaultTmpPath)
- }).catch(err => {
- reject(err)
- });
- }
- });
- },
- // 添加默认水印
- async addWatermark(index,imgInfo,newPath) {
- return new Promise((resolve,reject) => {
- let authority = this.$refs.headerRef.authority;
- if (authority.isAuthority) {
- // 有权限,则不做任何操作
- resolve(true)
- } else {
- this.initSysWater(imgInfo).then(re => {
- let sysDefaultTmpPath = re;
- // 合并系统水印
- let params2 = [
- 'convert.exe',
- '-monitor',
- newPath,
- sysDefaultTmpPath,
- '-gravity',
- 'center',
- '-composite',
- newPath
- ];
- electronApi.spawnExec(params2).then(result => {
- resolve(result)
- }).catch(err => {
- reject(err)
- });
- }).catch(err2 =>{
- reject({err2})
- });
- }
- })
- },
- deleteSysWtater(){
- let w1 = os.tmpdir()+separator+'water_xy_16.png';
- let w2 = os.tmpdir()+separator+'water_xy_28.png';
- let w3 = os.tmpdir()+separator+'water_xy_40.png';
- let w4 = os.tmpdir()+separator+'water_xy_100.png';
- if(fs.existsSync(w1)){
- fs.unlinkSync(w1);
- }
- if(fs.existsSync(w2)){
- fs.unlinkSync(w2);
- }
- if(fs.existsSync(w3)){
- fs.unlinkSync(w3);
- }
- if(fs.existsSync(w4)){
- fs.unlinkSync(w4);
- }
- },
-
- // 翻转模式
- flipChange(str){
- if(this.handleData[str]){
- this.handleData[str] = false;
- }else{
- this.handleData[str] = str;
- }
- },
-
- // 旋转角度
- rotateChange(type){
- let current = this.handleData.rotateValue;
- if(type == 1){ // 逆时针旋转90°
- current -= 90;
- if(current < -360){
- this.handleData.rotateValue = current + 360;
- }else{
- this.handleData.rotateValue = current;
- }
- }else{ // 顺时针旋转90°
- current += 90;
- if(current > 360){
- this.handleData.rotateValue = current - 360;
- }else{
- this.handleData.rotateValue = current;
- }
- }
- },
-
- // 删除重命名文件
- delImgFile(rowIndex){
- this.$confirm('确认删除这张图片吗?', '提示', {
- confirmButtonText: '确定',
- cancelButtonText: '取消',
- type: 'warning'
- }).then(() => {
- this.imgList.splice(rowIndex, 1);
- if (this.imgList.length == 0) {
- this.clearList();
- }
- }).catch(() => {
-
- });
- },
-
- // 重命名操作
- setChange() {
- let list = JSON.parse(JSON.stringify(this.imgList));
- list.map((item, key) => {
- let lastIndex = item.name.lastIndexOf('.');
- let fileName = item.name.substring(0, lastIndex);
- let fileExtend = item.name.substr(lastIndex+1);
-
- // ------------------文件名---------------------
- let newFilename = '', newExtendname = '';
- let fileNo = (this.handleRename.increment * key) + this.handleRename.startNumber;
- if(fileNo.toString().length < this.handleRename.digit){
- let size = this.handleRename.digit - fileNo.toString().length;
- let digitStr = "";
- for(let i = 0; i < size; i++){
- digitStr += "0";
- }
- fileNo = digitStr + fileNo;
- }
- newFilename = this.handleRename.fileName ? this.handleRename.fileName + fileNo : fileNo;
- // 文件名大小写转换
- newFilename = newFilename.toString();
- switch(this.handleRename.fileCase){
- case "2": // 全部大写
- newFilename = newFilename.toUpperCase();
- break;
- case "3": // 全部小写
- newFilename = newFilename.toLowerCase();
- break;
- case "4": // 首字母大写
- newFilename = newFilename.charAt(0).toUpperCase() + newFilename.slice(1);
- break;
- case "5": // 首字母小写
- newFilename = newFilename.charAt(0).toLowerCase() + newFilename.slice(1);
- break;
- }
- item.newName = newFilename + '.' + fileExtend;
- });
-
- this.imgList = JSON.parse(JSON.stringify(list));
- },
- // 重命名
- exportRename() {
- let authority = this.$refs.headerRef.authority;
- let tempList = [];
- this.renameLoading = this.$loading({
- lock: true,
- text: '批量操作中,请稍后...',
- spinner: 'el-icon-loading',
- background: 'rgba(0, 0, 0, 0.7)'
- });
- setTimeout(() => {
- this.renameLoading.close();
- this.renameModal = true;
- // this.$alert('重命名成功', '提示', {
- // confirmButtonText: '确定',
- // callback: action => {
- // this.setChange();
- // }
- // });
- this.imgList = JSON.parse(JSON.stringify(tempList));
- }, 3000);
-
- tempList = JSON.parse(JSON.stringify(this.imgList));
-
- let size = 999999999;
- if(!authority.isAuthority){
- size = 10;
- }
-
- setTimeout(()=>{
- for(let index = 0; index < tempList.length; index++) {
- let item = tempList[index];
- item.status = "1";
- let path = pathMod.dirname(item.path) + "\\";
- let newPath = path + item.newName;
- if(index < size) {
- fs.exists(path+item.name, (exists) => {
- if (exists) {
- fs.exists(newPath, (new_exists) => {
- if(!new_exists) {
- fs.rename(path+item.name, newPath, (err) => {
- if(err){
- item.status = "3"; throw err;
- }else{
- item.status = "2"; // 修改成功
- item.name = item.newName;
- item.path = newPath;
- }
- });
- } else {
- item.status = "5"; // 文件已存在
- }
- })
- } else {
- item.status = "4"; // 文件被修改
- }
- });
- }
- }
- }, 200);
- },
-
- // 拖拽排序
- dragEnd(event){
- this.sortChange(this.mergeData.sortType);
- },
-
- // 删除拼接图片
- deleteMerge(index, tips){
- this.$confirm('确认删除这张图片吗?', '提示', {
- confirmButtonText: '确定',
- cancelButtonText: '取消',
- type: 'warning'
- }).then(() => {
- if(tips == 'crop'){ // 删除裁剪图片
- this.cropList.splice(index, 1);
- if(this.cropList.length > 0){
- this.cropImgIndex = 0;
- this.cropOptions.img = this.cropList[0].path;
- this.cropOptionsImgInfo = this.cropList[0];
- this.cropImgLoading = false;
- }
-
- }else{
- this.mergeList.splice(index, 1);
- this.sortChange(this.mergeData.sortType);
- }
- }).catch(() => {
-
- });
- event.stopPropagation();
- },
- // 移动图片
- move(id){
- let that = this;
- let obj = document.getElementById('merge-imgId-'+id);
- let currentWidth = obj.offsetWidth; // 当前元素的宽
- let currentHeight = obj.offsetHeight; // 当前元素的高
- let parentWidth = obj.parentElement.offsetWidth; // 父元素的宽
- let parentHeight = obj.parentElement.offsetHeight; // 父元素的高
- obj.onmousedown = function(e) { //鼠标按下事件
- e = e || window.event; //事件对象
- let x_down = e.clientX; //鼠标按下X的坐标
- let y_down = e.clientY; //鼠标按下Y的坐标
- let leftDown = this.offsetLeft; //获取盒子的初始left值
- let topDown = this.offsetTop; //获取盒子的初始top值
- obj.parentElement.style.border = "2px solid #ed4014";
- document.onmousemove = function(e) { //鼠标移动事件
- // console.log(e.fromElement, e.toElement);
- e = e || window.event;
- let x_move = e.clientX; //鼠标移动X的坐标
- let y_move = e.clientY; //鼠标移动Y的坐标
- //移动的坐标减去按下的坐标 = 移动的距离
- let x_now = x_move - x_down;
- let y_now = y_move - y_down;
- let top = topDown + y_now;
- let left = leftDown + x_now;
- //赋值给left和top
- obj.style.top = top / parentHeight * 100 + '%'; //top + 'px';
- obj.style.left = left / parentWidth * 100 + '%'; //left + 'px';
- if(top > 0){
- top = 0;
- obj.style.top = 0;
- }
- if(left > 0){
- left = 0;
- obj.style.left = 0;
- }
- if(left < parentWidth - currentWidth ){
- left = parentWidth - currentWidth;
- obj.style.left = (parentWidth - currentWidth) / parentWidth * 100 + '%'; //parentWidth - currentWidth + 'px';
- }
- if(top < parentHeight - currentHeight){
- top = parentHeight - currentHeight;
- obj.style.top = (parentHeight - currentHeight) / parentHeight * 100 + '%'; //parentHeight - currentHeight + 'px';
- }
- that.mergeList[id].top = Math.abs(top / parentHeight);
- that.mergeList[id].left = Math.abs(left / parentWidth);
- }
- document.onmouseup = function() { //鼠标抬起事件
- //清除移动和抬起事件
- obj.parentElement.style.border = "none";
- this.onmousemove = this.onmouseup = null;
- }
- return false //阻止默认事件
- }
- },
- //
- outWidthChange(e){
- let scale = Number(this.mergeData.scale.split(':')[0]) / Number(this.mergeData.scale.split(':')[1]);
- this.mergeData.outHeight = Math.round(this.mergeData.outWidth / scale);
- if(this.mergeData.sortType == 3){
- this.mergeData.height = this.mergeData.outHeight;
- this.mergeData.width = this.mergeData.outWidth;
- }
- },
-
- //
- outHeightChange(e){
- let scale = Number(this.mergeData.scale.split(':')[0]) / Number(this.mergeData.scale.split(':')[1]);
- this.mergeData.outWidth = Math.round(this.mergeData.outHeight * scale);
- if(this.mergeData.sortType == 3){
- this.mergeData.height = this.mergeData.outHeight;
- this.mergeData.width = this.mergeData.outWidth;
- }
- },
-
- //
- widthChange(e){
- let scale = Number(this.mergeData.scale.split(':')[0]) / Number(this.mergeData.scale.split(':')[1]);
- if(this.mergeData.lockScale){ // 锁定比例
- this.mergeData.height = Math.round(this.mergeData.width / scale);
- }
- let percent = this.mergeData.height / this.mergeData.width * 50;
- this.mergeData.autoStyle = "padding-top: " + percent + "%;";
- },
-
- //
- heightChange(e){
- let scale = Number(this.mergeData.scale.split(':')[0]) / Number(this.mergeData.scale.split(':')[1]);
- if(this.mergeData.lockScale){ // 锁定比例
- this.mergeData.width = Math.round(this.mergeData.height * scale);
- }
- let percent = this.mergeData.height / this.mergeData.width * 50;
- this.mergeData.autoStyle = "padding-top: " + percent + "%;";
- },
-
- //
- sizeChange(e){
- if(this.mergeData.sortType == 1){ // 1、横图 2、竖图
- let spaceReal = this.mergeList[0].height * this.mergeData.space / 500;
- let borderReal = this.mergeList[0].height * this.mergeData.border / 500;
- this.mergeData.width = Number((this.mergeData.contentWidth + spaceReal * (this.mergeList.length - 1) + borderReal * 2).toFixed(0));
- this.mergeData.height = Number((this.mergeData.contentHeight + borderReal * 2).toFixed(0));
- }else if(this.mergeData.sortType == 2){
- let spaceReal = this.mergeList[0].width * this.mergeData.space / 500;
- let borderReal = this.mergeList[0].width * this.mergeData.border / 500;
- this.mergeData.width = Number((this.mergeData.contentWidth + borderReal * 2).toFixed(0));
- this.mergeData.height = Number((this.mergeData.contentHeight + spaceReal * (this.mergeList.length - 1) + borderReal * 2).toFixed(0));
- }
- this.mergeData.scale = this.mergeData.width + ':' + this.mergeData.height;
- let scale = Number(this.mergeData.scale.split(':')[0]) / Number(this.mergeData.scale.split(':')[1]);
- if(this.mergeData.sortType == 1){
- this.mergeData.outWidth = Math.round(this.mergeData.outHeight * scale);
- }else if(this.mergeData.sortType == 2){
- this.mergeData.outHeight = Math.round(this.mergeData.outWidth / scale);
- }
- },
-
- // 失焦事件
- numBlur(str){
- if(!this.mergeData[str]){
- this.mergeData[str] = 0;
- }
- },
-
- // 选择排序模式 1、横图 2、竖图 3、自定义
- sortChange(e){
- let canvasWidth = 0;
- let canvasHeight = 0;
- if(e == 1){
- canvasWidth = 0;
- canvasHeight = this.mergeList[0].height;
- this.mergeList.map(item => {
- let width = Number(canvasHeight * (item.width / item.height));
- canvasWidth = canvasWidth + width;
- })
- }else if(e == 2){
- canvasWidth = this.mergeList[0].width;
- canvasHeight = 0;
- this.mergeList.map(item => {
- let height = Number(canvasWidth / (item.width / item.height));
- canvasHeight = canvasHeight + height;
- })
- }else{
- canvasWidth = 1200;
- canvasHeight = 1200;
- this.mergeData.autoStyle = 'padding-top: 50%;';
- }
- this.mergeData.contentWidth = Number(canvasWidth.toFixed(0));
- this.mergeData.contentHeight = Number(canvasHeight.toFixed(0));
- this.mergeData.width = Number(canvasWidth.toFixed(0));
- this.mergeData.height = Number(canvasHeight.toFixed(0));
- this.mergeData.scale = this.mergeData.width + ':' + this.mergeData.height;
- this.mergeData.outWidth = Number(canvasWidth.toFixed(0));
- this.mergeData.outHeight = Number(canvasHeight.toFixed(0));
- this.sizeChange();
- },
-
- // 缩放
- zoom(flag){
- if(flag == 'reduce'){ // 缩小
- if(this.mergeData.zoom > 0.7){
- this.mergeData.zoom -= 0.1;
- }
- }else{ // 放大
- if(this.mergeData.zoom < 2){
- this.mergeData.zoom += 0.1;
- }
- }
- },
-
- // 修改画布大小
- canvasChange(e){
- let regex = /([1-9]*:[1-9]*)/g;
- let val = e.match(regex)[0];
- let str = 'padding-top: 50%;';
- let width = 1200;
- let height = 1200;
- switch(val){
- case '1:1': // 1:1 1200:1200
- str = 'padding-top: 50%;';
- width = 1200;
- height = 1200;
- break;
- case '2:3': // 2:3 1200:1800
- str = 'padding-top: 75%;';
- width = 1200;
- height = 1800;
- break;
- case '3:2': // 3:2 1800:1200
- str = 'padding-top: 33.333%;';
- width = 1800;
- height = 1200;
- break;
- case '3:4': // 3:4 1200:1600
- str = 'padding-top: 66.666%;';
- width = 1200;
- height = 1600;
- break;
- case '4:3': // 4:3 1600:1200
- str = 'padding-top: 37.5%;';
- width = 1600;
- height = 1200;
- break;
- case '16:9': // 16:9 1920:1080
- str = 'padding-top: 28.125%;';
- width = 1920;
- height = 1080;
- break;
- case '9:16': // 9:16 1080:1920
- str = 'padding-top: 88.888%;';
- width = 1080;
- height = 1920;
- break;
- }
- this.mergeData.autoStyle = str;
- this.mergeData.width = width;
- this.mergeData.height = height;
- this.mergeData.outWidth= width;
- this.mergeData.outHeight = height;
- this.mergeData.scale = val;
- },
-
- // 自定义块样式
- blockStyle(flag){
- let str = '';
- let spacePix = this.mergeData.width * (this.mergeData.space / 10 / 100); //间距的宽度 -> 间距的百分比以宽为基数
- let heightSpace = spacePix / this.mergeData.height * 100;
-
- if(flag == 'height'){
- str = 'height: ' + (100 / this.mergeData.row - (heightSpace * (this.mergeData.row - 1) / this.mergeData.row)) + '%;'
- }else{
- str = 'width:' + (100 / this.mergeData.col - (this.mergeData.space / 10 * (this.mergeData.col - 1) / this.mergeData.col)) + '%;border-radius:'+ this.mergeData.radius / 2 +'%;'
- }
- return str;
- },
-
- // 行数列数发生变化 图片位置初始化0
- rowColChange(){
- let num = this.mergeData.row * this.mergeData.col;
- this.mergeList.map((item, index) => {
- item.top = 0;
- item.left = 0;
- if(index < num && document.getElementById('merge-imgId-'+index)){
- document.getElementById('merge-imgId-'+index).style.top = 0;
- document.getElementById('merge-imgId-'+index).style.left = 0;
- }
- })
- },
-
- // 图片自适应宽高
- picStyle(index){
- let imgWidth = this.mergeList[index].width; // 图高
- let imgHeight = this.mergeList[index].height; // 图高
- let blockWidth = this.mergeData.width / this.mergeData.col; // 块宽
- let blockHeight = this.mergeData.height / this.mergeData.row; // 块高
- let str = "width: 100%;";
- let fillType = "width";
-
- if(imgWidth > imgHeight){
- if(blockWidth <= blockHeight){
- str = "height: 100%";
- fillType = "height";
- }else{
- str = (blockWidth / blockHeight) >= (imgWidth / imgHeight) ? "width:100%;" : "height:100%;";
- fillType = (blockWidth / blockHeight) >= (imgWidth / imgHeight) ? "width" : "height";
- }
- }else{
- if(blockWidth >= blockHeight){
- str = "width: 100%;";
- fillType = "width";
- }else{
- if(imgWidth == imgHeight){
- str = "height:100%;";
- fillType = "height";
- }else{
- str = blockWidth / blockHeight >= imgWidth / imgHeight ? "width:100%;" : "height:100%;";
- fillType = blockWidth / blockHeight >= imgWidth / imgHeight ? "width" : "height";
- }
- }
- }
- this.mergeList[index].fillType = fillType;
- return str;
- },
-
- // 图片拼接-自定义
- exportMerge(){ // 先按照移动比列裁剪 在拼接图片
- //convert src.jpg -resize 500x500 -crop 100x80+50+30 dest.jpg
- clearInterval(this.mergeInterval);
- this.mergeLoading = this.$loading({
- lock: true,
- text: '图片处理中,请稍后...',
- spinner: 'el-icon-loading',
- background: 'rgba(0, 0, 0, 0.7)'
- });
- setTimeout(()=>{ // 3分钟后加载层消失防止进程出错
- this.mergeLoading.close();
- }, 1000 * 60 * 3);
- let borderWidth = this.mergeData.width * (this.mergeData.border / 10 / 100); // 边框的宽度
- let spaceWidth = this.mergeData.width * (this.mergeData.space / 10 / 100);; // 间距的宽度
- let blockWidth = (this.mergeData.width - borderWidth * 2 - spaceWidth * (this.mergeData.col - 1)) / this.mergeData.col; // 块宽
- let blockHeight = (this.mergeData.height - borderWidth * 2 - spaceWidth * (this.mergeData.row - 1)) / this.mergeData.row; // 块高
- let radiusWidth = this.mergeData.radius / 2 / 100 * blockWidth || 0;
-
- let newFolderPath = this.handleData.newPath;
- let newTime = new Date().getTime();
- fs.mkdirSync(os.tmpdir() + separator + pjson.softInfo.softMid+newTime);
- newFolderPath = os.tmpdir() + separator + pjson.softInfo.softMid+newTime;
- let dealNum = 0;
- let errorIndex = -1;
- let imgParamsArr = []; // 所有图片的位置参数
-
- // 生成圆角MASK遮盖层 convert -size "$W"x"$H" xc:none -draw "roundrectangle 0,0,$W,$H,$R,$R" $MASK
- let maskPath = os.tmpdir()+separator+'radius.png';
- let radiusStr = 'roundrectangle 0,0,'+blockWidth+','+blockHeight+','+radiusWidth+','+radiusWidth;
- if(this.mergeData.radius == 0){
- radiusStr = 'rectangle 0,0,'+blockWidth+','+blockHeight;
- }
- let paramsRadius = [
- 'convert.exe',
- '-size',
- blockWidth+'x'+blockHeight,
- 'xc:none',
- '-draw',
- radiusStr,
- maskPath
- ];
- electronApi.spawnExec(paramsRadius).then(res => {
- setTimeout(() => { // 延迟执行
- for(let index = 0; index < this.mergeList.length; index++){
- let item = this.mergeList[index];
- if(index < this.mergeData.row * this.mergeData.col){ // 自定义排序
- let imgRealWidth = 0;
- let imgRealHeight = 0;
- let top = 0;
- let left = 0;
- let cropParams = [];
-
- if(this.mergeData.mergeType == 1){ // 自适应模式
- if(item.fillType == 'width'){
- imgRealHeight = blockHeight;
- imgRealWidth = imgRealHeight * (item.width / item.height);
- }else{
- imgRealWidth = blockWidth;
- imgRealHeight = imgRealWidth / (item.width / item.height);
- }
- top = (blockHeight - imgRealHeight) / 2;
- left = (blockWidth - imgRealWidth) / 2;
- }else{ // 自定义裁剪模式
- if(item.fillType == 'width'){
- imgRealWidth = blockWidth;
- imgRealHeight = imgRealWidth / (item.width / item.height);
- }else{
- imgRealHeight = blockHeight;
- imgRealWidth = imgRealHeight * (item.width / item.height);
- }
- top = item.top * blockHeight;
- left = item.left * blockWidth;
- cropParams = ['-crop',blockWidth+'x'+blockHeight+'+'+left+'+'+top];
- }
-
- let newTime2 = new Date().getTime();
- let newPath = newFolderPath + separator + item.name.slice(0, item.name.lastIndexOf('.')) +newTime2+Math.random()+ '.png';
- // convert $SRC -matte $MASK -compose DstIn -composite $TMP_PNG
- let params = [
- 'convert.exe',
- item.path,
- '-resize',
- imgRealWidth+'x'+imgRealHeight,
- ...cropParams,
- '-matte',
- maskPath,
- '-compose',
- 'DstIn',
- '-composite',
- newPath
- ];
-
- let currentRow = Math.floor(index / this.mergeData.col) + 1;
- let currentCol = index % this.mergeData.col + 1;
-
- let imgPositionX = borderWidth + blockWidth * (currentCol - 1) + spaceWidth * (currentCol - 1);
- let imgPositionY = borderWidth + blockHeight * (currentRow - 1) + spaceWidth * (currentRow - 1);
- if(this.mergeData.mergeType == 1){ // 自适应
- imgPositionX = imgPositionX + left;
- imgPositionY = imgPositionY + top;
- }
- let imgParams = [newPath, '-geometry', '+'+imgPositionX+'+'+imgPositionY, '-composite'];
-
- electronApi.spawnExec(params).then(res => {
- dealNum ++;
- imgParamsArr = imgParamsArr.concat(imgParams);
- }).catch(err => {
- this.mergeLoading.close();
- errorIndex = index;
- this.$notify.error({
- title: '第【'+Number(index+1)+'】张图片出错',
- message: '请调整后重试!' + err.stderr.toString()
- });
- });
- }
- }
-
- this.mergeInterval = setInterval(() => {
- if(this.mergeData.row * this.mergeData.col == dealNum || dealNum == this.mergeList.length){ // 裁剪完成 准备拼接图片
- clearInterval(this.mergeInterval);
- // 拼接命令参数 ['2.jpg', '-geometry', '+256+0', '-composite'];
- let suffix = '.jpg';
- if(Number(this.mergeData.backgroundColor.match(/[\d.]+/g)[3]) < 1){
- suffix = '.png';
- }
- let outPath = this.handleData.newPath+separator+pjson.softInfo.softName+separator+'图片拼接'+this.$utils.formatTime(newTime/1000)+suffix;
- let params2 = [
- 'convert.exe',
- '-size',
- this.mergeData.width+'x'+this.mergeData.height,
- '-strip',
- 'xc:'+this.mergeData.backgroundColor,
- ...imgParamsArr,
- outPath
- ];
-
- electronApi.spawnExec(params2).then(res => {
- this.mergeLoading.close();
- this.$message({message: '恭喜你,图片拼接完成!', type: 'success'});
- try{
- // 未购买 添加系统水印
- this.addWatermark(0, {width:this.mergeData.width, height: this.mergeData.height}, outPath);
- // 删除裁剪的图片
- fs.readdir(newFolderPath, (err, files) => {
- for (let i = 0; i < files.length; i++) {
- let statFile = newFolderPath+separator+files[i];
- fs.unlinkSync(statFile);
- }
- fs.rmdir(newFolderPath, (err) => {
- if(err){
- console.log(err);
- }
- });
- });
- }catch(e){
- console.log(e);
- }
- setTimeout(() => { // 延迟打开
- electronApi.call('showItemInfolder',[outPath])
- }, 1000);
- }).catch(err => {
- this.mergeLoading.close();
- this.$notify.error({
- title: '图片拼接失败-3',
- message: '请调整后重试!' + err.stderr.toString()
- });
- });
- }else if(errorIndex >= 0){ // 文件处理出错
- clearInterval(this.mergeInterval);
- }
- }, 1000);
- }, 300)
- }).catch(err => {
- this.mergeLoading.close();
- this.$notify.error({
- title: '图片【'+Number(index+1)+'】出错',
- message: '请调整后重试!遮盖层' + err.stderr.toString()
- });
- console.log('圆角遮盖层创建失败',err.stderr.toString())
- });
- },
- // 图片拼接-横图和竖图
- exportMerge2(){ // 先按照移动比列裁剪 在拼接图片
- //convert src.jpg -resize 500x500 -crop 100x80+50+30 dest.jpg
- clearInterval(this.mergeInterval);
- this.mergeLoading = this.$loading({
- lock: true,
- text: '图片处理中,请稍后...',
- spinner: 'el-icon-loading',
- background: 'rgba(0, 0, 0, 0.7)'
- });
- setTimeout(()=>{ // 3分钟后加载层消失防止进程出错
- this.mergeLoading.close();
- }, 1000 * 60 * 3);
-
- let newFolderPath = this.handleData.newPath;
- let newTime = new Date().getTime();
- fs.mkdirSync(os.tmpdir() + separator + pjson.softInfo.softMid+newTime);
- newFolderPath = os.tmpdir() + separator + pjson.softInfo.softMid+newTime;
-
- setTimeout(async() => { // 延迟执行
- let contentWidth = 0, contentHeight = 0;
- let dealNum = 0;
- let errorIndex = -1;
- let imgParamsArr = []; // 所有图片的位置参数
- for(let index = 0; index < this.mergeList.length; index++){
- let item = this.mergeList[index];
- let firstItem = this.mergeList[0];
-
- let borderWidth = 0, spaceWidth = 0, blockWidth = 0, blockHeight = 0, radiusWidth = 0;
- if(this.mergeData.sortType == 1){ // 横版
- borderWidth = firstItem.height * (this.mergeData.border / 500); // 边框的宽度
- spaceWidth = firstItem.height * (this.mergeData.space / 500); // 间距的宽度
- blockWidth = item.width / (item.height / firstItem.height);
- blockHeight = firstItem.height;
- radiusWidth = this.mergeData.radius / 2 / 100 * blockWidth || 0;
- }else if(this.mergeData.sortType == 2){ // 竖版
- borderWidth = firstItem.width * (this.mergeData.border / 500); // 边框的宽度
- spaceWidth = firstItem.width * (this.mergeData.space / 500); // 间距的宽度
- blockHeight = item.height / (item.width / firstItem.width);
- blockWidth = firstItem.width;
- radiusWidth = this.mergeData.radius / 2 / 100 * blockWidth || 0;
- }
-
- // 生成圆角MASK遮盖层 convert -size "$W"x"$H" xc:none -draw "roundrectangle 0,0,$W,$H,$R,$R" $MASK
- let maskPath = os.tmpdir()+separator+'radius'+index+'.png';
- let radiusStr = 'roundrectangle 0,0,'+blockWidth+','+blockHeight+','+radiusWidth+','+radiusWidth;
- if(this.mergeData.radius == 0){
- radiusStr = 'rectangle 0,0,'+blockWidth+','+blockHeight;
- }
- let paramsRadius = [
- 'convert.exe',
- '-size',
- blockWidth+'x'+blockHeight,
- 'xc:none',
- '-draw',
- radiusStr,
- maskPath
- ];
- await electronApi.spawnExec(paramsRadius).then(async(res) => {
- let newTime2 = new Date().getTime();
- let newPath = newFolderPath + separator + item.name.slice(0, item.name.lastIndexOf('.')) +newTime+Math.random()+ '.png';
- let params = [
- 'convert.exe',
- item.path,
- '-resize',
- blockWidth+'x'+blockHeight,
- '-matte',
- maskPath,
- '-compose',
- 'DstIn',
- '-composite',
- newPath
- ];
-
- contentWidth += blockWidth;
- contentHeight += blockHeight;
-
- let imgPositionX = 0;
- let imgPositionY = 0;
- if(this.mergeData.sortType == 1){ // 横版
- imgPositionX = borderWidth + (contentWidth - blockWidth) + spaceWidth * index;
- imgPositionY = borderWidth;
- }else if(this.mergeData.sortType == 2){ // 竖版
- imgPositionX = borderWidth;
- imgPositionY = borderWidth + (contentHeight - blockHeight) + spaceWidth * index;
- }
-
- let imgParams = [newPath, '-geometry', '+'+imgPositionX+'+'+imgPositionY, '-composite'];
- await electronApi.spawnExec(params).then(res => {
- dealNum ++;
- imgParamsArr = imgParamsArr.concat(imgParams);
- }).catch(err => {
- this.mergeLoading.close();
- errorIndex = index;
- this.$notify.error({
- title: '图片【'+Number(index+1)+'】出错',
- message: '请调整后重试!' + err.stderr.toString()
- });
- });
- }).catch(err => {
- this.mergeLoading.close();
- this.$notify.error({
- title: '图片【'+Number(index+1)+'】出错',
- message: '请调整后重试!遮盖层' + err.stderr.toString()
- });
- console.log('圆角遮盖层创建失败',err.stderr.toString())
- });
- }
-
- this.mergeInterval = setInterval(() => {
- if(dealNum == this.mergeList.length){ // 裁剪完成 准备拼接图片
- clearInterval(this.mergeInterval);
- // 拼接命令参数 ['2.jpg', '-geometry', '+256+0', '-composite'];
- let suffix = '.jpg';
- if(Number(this.mergeData.backgroundColor.match(/[\d.]+/g)[3]) < 1){
- suffix = '.png';
- }
- let outPath = this.handleData.newPath+separator+pjson.softInfo.softName+separator+'图片拼接'+this.$utils.formatTime(newTime/1000)+suffix;
- let params2 = [
- 'convert.exe',
- '-size',
- this.mergeData.width+'x'+this.mergeData.height,
- '-strip',
- 'xc:'+this.mergeData.backgroundColor,
- ...imgParamsArr,
- '-resize',
- Number(this.mergeData.outWidth / this.mergeData.width) * 100 + '%',
- outPath
- ];
-
- electronApi.spawnExec(params2).then(res => {
- this.mergeLoading.close();
- this.$message({message: '恭喜你,图片拼接完成!', type: 'success'});
- try{
- // 未购买 添加系统水印
- this.addWatermark(0, {width:this.mergeData.outWidth, height: this.mergeData.outHeight}, outPath);
- // 删除裁剪的图片
- fs.readdir(newFolderPath, (err, files) => {
- for (let i = 0; i < files.length; i++) {
- let statFile = newFolderPath+separator+files[i];
- fs.unlinkSync(statFile);
- }
- fs.rmdir(newFolderPath, (err) => {
- if(err){
- console.log(err);
- }
- });
- });
- }catch(e){
- console.log(e);
- }
- setTimeout(() => { // 延迟打开
- electronApi.call('showItemInfolder',[outPath])
- }, 1000);
- }).catch(err => {
- this.mergeLoading.close();
- this.$notify.error({
- title: '图片拼接失败',
- message: '请调整后重试!' + err.stderr.toString()
- });
- });
- }else if(errorIndex >= 0){ // 文件处理出错
- clearInterval(this.mergeInterval);
- }
- }, 1000);
- }, 300)
- },
- }
- };
- </script>
- <style lang="scss">
- @import '../assets/css/font/iconfont.css';
- @import '../assets/css/home.scss';
-
- .ivu-input-number-controls-outside-btn i{
- font-weight: 800;
- }
-
- .update-point{
- display: inline-block;
- width: 8px;
- height: 8px;
- border-radius: 8px;
- background: #ff0000;
- top: 14px;
- position: absolute;
- left: -13px;
- }
-
- .title-flex{
- display: flex;
- flex-wrap: nowrap;
- justify-content: flex-start;
- }
- .demo-spin-icon-load{
- animation: ani-demo-spin 1s linear infinite;
- }
-
- .line-density{
- display: inline-block;
- width: calc(100% - 74px);
- }
-
- .handle-item{
- .handle-label{
- width: 70px;
- }
- .ivu-input-number-handler-wrap{
- opacity: 1;
- }
- }
-
- .set-height{
- height: 100%;
- }
-
- .merge-flex{
- padding: 10px;
- height: 100%;
- display: flex;
- flex-wrap: nowrap;
- justify-content: flex-start;
-
- .merge-content{
- width: calc(100% - 140px);
- height: 100%;
- }
-
- .merge-top{
- overflow: hidden;
- margin-bottom: 10px;
- display: flex;
- flex-wrap: nowrap;
- justify-content: space-between;
- }
-
- .action-right{
- width: 70px;
- display: flex;
- flex-wrap: nowrap;
- justify-content: space-between;
- line-height: 1;
- cursor: pointer;
-
- .action-ritem:hover{
- color: #ce0000;
- }
-
- .iconfont{
- font-size: 20px;
- }
- }
-
- .merge-left{
- width: 110px;
- text-align: center;
- height: 100%;
- overflow-y: auto;
- }
- .img-area{
- width: 90px;
- height: 60px;
- text-align: center;
- line-height: 56px;
- border: 1px solid #ddd;
- }
- .merge-scroll{
- display: flex;
- flex-wrap: nowrap;
- overflow: hidden auto;
- position: relative;
- width: 130px;
- flex-direction: column;
- margin-right: 8px;
- }
- .merge-item{
- width: 90px;
- margin-bottom: 10px;
- }
- .merge-imgdel{
- position: absolute;
- right: -8px;
- top: 0px;
- font-size: 12px;
- padding: 2px;
- background-color: #ccc;
- border-radius: 50%;
- color: #fff;
- cursor: pointer;
- &:hover{
- background-color: #ce0000;
- }
- }
- .mergelist-img{
- max-width: 100%;
- max-height: 100%;
- vertical-align: middle;
- }
- .merge-name{
- overflow: hidden;
- text-overflow:ellipsis;
- white-space: nowrap;
- margin-bottom: 5px;
- }
- .mer-title{
- font-weight: 600;
- margin-bottom: 10px;
- }
- }
-
- ::-webkit-scrollbar {
- /*滚动条整体样式*/
- width: 6px; /*高宽分别对应横竖滚动条的尺寸*/
- height: 6px;
- }
- ::-webkit-scrollbar-thumb {
- /*滚动条里面小方块*/
- border-radius: 10px;
- box-shadow: inset 0 0 5px rgba(97, 184, 179, 0.1);
- background: #666;
- }
- ::-webkit-scrollbar-track {
- /*滚动条里面轨道*/
- box-shadow: inset 0 0 5px rgba(87, 175, 187, 0.1);
- border-radius: 10px;
- background: #ededed;
- }
-
- .mlist-scroll{
- overflow: auto;
- background-color: #fff;
- padding: 5px;
- height: calc(100% - 45px);
-
- &.bgmini{
- background: url('../assets/image/bgmini.png');
- }
-
- .mlist-content{
- width: 50%;
- position: relative;
- box-shadow: 2px 2px 6px #ddd, -2px -2px 6px #ddd;
- margin: auto;
- transform-origin: 50% 0;
- }
- .mlist-area{
- position: absolute;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- display: flex;
- flex-wrap: nowrap;
- flex-direction: column;
- justify-content: space-between;
- }
- .merge-row{
- display: flex;
- flex-wrap: nowrap;
- justify-content: space-between;
- width: 100%;
- }
- .merge-col{
- text-align: center;
- overflow: hidden;
- position: relative;
- &:hover{
- // border: 2px solid #2b83e0;
- }
- }
- .merge-img{
- position: absolute;
- top: 0;
- left: 0;
- cursor:move;
- }
- .merge-img2{
- max-width: 100%;
- max-height: 100%;
- vertical-align: middle;
- position: absolute;
- top: 0 !important;
- left: 0 !important;
- right: 0 !important;
- bottom: 0 !important;
- margin: auto;
- }
- .merge-add{
- font-size: 50px;
- border: 1px solid #ccc;
- height: 100%;
- background-color: #fafafa;
- display: flex;
- align-items: center;
- justify-content: center;
- cursor: pointer;
- &:hover{
- background-color: #f3f3f3;
- }
- }
- }
-
- .disnone{
- display: none;
- }
-
- // 横图
- .horizontal-scroll{
- width: 80%;
- margin: auto;
- height: 250px;
- margin-top: 10%;
- box-shadow: 2px 2px 6px #ddd, -2px -2px 6px #ddd;
- overflow: auto;
- box-sizing: content-box;
- }
- .horizontal-content{
- height: 100%;
- display: flex;
- flex-wrap: nowrap;
- justify-content: flex-start;
- .horizontal-item{
- display: flex;
- }
- .horizontal-area{
- display: inline-block;
- height: 100%;
- }
- .horizontal-img{
- height: 100%;
- box-sizing: content-box;
- flex-shrink: 0;
- &:last-child{
- margin-right: 0 !important;
- }
- }
- }
-
- // 竖图
- .vertical-content{
- width: 250px;
- margin: auto;
- box-shadow: 2px 2px 6px #ddd, -2px -2px 6px #ddd;
- box-sizing: content-box;
- .vertical-img{
- width: 100%;
- display: inherit;
- &:last-child{
- margin-bottom: 0 !important;
- }
- }
- }
-
- .i-fanzhuan{
- font-size: 25px;
- margin-right: 20px;
- cursor: pointer;
-
- &:hover,&.active{
- color: #ce0000;
- }
- }
-
- .flex-crop{
- display: flex;
- flex-wrap: wrap;
- justify-content: space-between;
-
- .crop-button{
- width: 65px;
- margin: 10px 0 !important;
- }
- }
-
- .show-preview{
- margin: auto;
- }
-
- .popper-open{
- text-align: center !important;
- padding: 10px !important;
- background: #303133 !important;
- color: #fff !important;
- min-width: 120px !important;
- opacity: 0.8;
- }
-
- .popper-open[x-placement^=bottom] .popper__arrow::after{
- border-bottom-color: #303133 !important;
- }
-
- .el-aside,.el-menu{
- border-right: none !important;
- }
-
- .vxebtn-del{
- position: absolute !important;
- right: 0;
- top: 10px;
- color: #F56C6C !important;
- z-index: 2;
- }
-
- .m-image{
- width: 25px;
- margin-right: 5px;
- }
-
- .el-menu-item.is-active{
- font-weight: 800;
- font-size: 16px;
- }
-
- .el-menu-item:hover{
- font-weight: 800;
- font-size: 16px;
- }
- </style>
|