Fórum pro uživatele kancelářského balíku OpenOffice | LibreOffice
 

#26 25. 2. 2020 17:48:07

barevnej
Člen
Registrace: 6. 8. 2015
Příspěvků: 171

Re: Hromadná komprimace fotografii

Případně mě napadá všechny fotky najednou změnit velikost na požadovanou výšku. Jenže ať najdu co najdu tak výsledek je že musím zadat i výslednou šířku což nevím když je každý obrázek jinak široký.

Offline

#27 25. 2. 2020 18:46:38

kamlan
Člen
Registrace: 15. 9. 2016
Příspěvků: 368

Re: Hromadná komprimace fotografii

Tak zkuste následující makro, udělal jsem to tedy pořádně, žádné hrubé splácnutí. Velikost buněk to zatím nijak nepřizpůsobuje.


Jestli ty buňky budou v jednom sloupci tak jim výšku řádků mohu zkusit přizpůsobovat snadno; ale kdyby měly být různě v dokumentu a měl bych kontrolovat jestli se přizpůsobením rozměru sloupce nebo řádku jedné buňky nezmění neblaze potřebný rozměr pro jinou buňku, tak by to byla nejspíš dost fuška a do toho se mi tedy nechce.


Potenciální nevýhoda je však při exportu, kdy všechno exportuje do JPG, takže možná může někdy nastat problém třeba s průhledností některých PNG. Nicméně možná by šlo udělat export do originálního formátu obrázku, to nyní nevím. Kdyby tohle mělo blbnout, tak bych pro další testy potřeboval pár testovacích obrázků na kterých to blbne.


S tím případným různým DPI zatím nevím jak naložit. XnView umí dávkově nastavit jednotné DPI pro obrázky, takže se to dá zpracovat v jedné dávce s transformací rozměrů - a pod Linuxem mi před pár lety normálně běhalo přes emulátor Wine. Ale s tou dávkovou konverzí rozměrů či DPI si jistě poradíte i bez XnView.


Ve Writeru vím, že to vkládané obrázky zvětšuje, takže vkládanému obrázku zvětším DPI o polovinu a vloží ho do dokumentu v běžné velikosti.

Např. když dám printscreen nějaké části obrazovky a pak rovnou Ctrl+V do Writeru, vloží se to o něco větší -> takže nejdřív otevřu obyčejné Malování, do něj Ctrl+V, uložím obrázek a v XnView mu dám o polovinu větší DPI (např. pokud má DPI 110 tak 110 + 110/2 = 165). S tímto o půlku zvětšeným DPI se pak vkládá v původní osnímkované velikosti.

Když však budou mít obrázky jednotné DPI, tak na jejich korekci velikosti lze využít koeficient iKoef, dal jsem ho na 2/3 což simuluje zvětšení DPI o polovinu - 2/3 je opačné hodnota z 3/2 čili z něčeho zvětšeného o půlku :-). Můžete zkusit dát ho třeba na 2 aby se obrázky zvětšily, pak uvidíte, že to přizpůsobení rozměrů buněk nemusí být od věci :-) - ale jak jsem zmínil na začátku, mnohem jednodušší by to bylo jen pro jeden sloupec než univerzálně pro celý dokument.


Pro pevnou výšku můžete zalaborovat s oSize.height, ale samozřejmě je k tomu potřeba správně napoměrovat i oSize.width.

Sub EXPORT_IMPORT_OBRAZKU 'exportuje ze Sešitu obrázky do adresáře Sešitu a po odsouhlasení hlášky importuje ony obrázky - před potvrzením hlášky se dají tedy upravit
	'on local error resume next 'při chybě pokračovat při chybě dál
	on local error goto chyba 'při chybě jít na návěští chyba
	const iKoef as long = 2/3 'koeficient kterým se násobí výška a šířka obrázku
	dim oDoc, oGP, p(1000000), i&, s$, pUrl(), oList, oImg, n&, oDrawPage, oBunka, sUrl$, oCur, oSize as object, oPos
	dim props(1) as new com.sun.star.beans.PropertyValue
	props(0).Name="URL" : props(1).Name="MimeType"
	const sLom$="/"
	oDoc=thisComponent 'aktuální Sešit
	
	rem EXPORT
	pUrl=split(oDoc.URL, sLom) 'pole pro url se jménem dokumentu
	oGP=createUnoService("com.sun.star.graphic.GraphicProvider") 'objekt grafické služby
	i=0 'kolik obrázků exportuje z dokumentu
	for each oList in oDoc.Sheets
		oDrawPage=oList.DrawPage
		for n=oDrawpage.Count-1 to 0 step -1
			oImg=oDrawpage.getByIndex(n) 'vybraný grafický objekt
			if oImg.supportsService("com.sun.star.drawing.GraphicObjectShape") then 'jde o obrázek
				pUrl(ubound(pUrl))=oImg.Name & ".jpg" 'poslední položka v poli je jméno Sešitu, takto nahradí příponou .jpg
				props(0).Value=convertToURL(join(pUrl, sLom)) : props(1).Value=oImg.Graphic.MimeType
				oGP.storeGraphic(oImg.Graphic, props) 'uložit obrázek
				s=join(pUrl,sLom) 'url obrázku
				p(i)=array(oImg.Anchor,s,oDrawPage) 'pole s buňkou a url příslušného obrázku pro ní
				oDrawpage.remove(oImg) 'odstranit obrázek
				i=i+1 'počet exportovaných obrázků
			end if
		next n
	next oList
	if i=0 then
		msgbox("Nebyl exportován žádný obrázek",48)
		exit sub
	end if
	redim preserve p(i-1) 'velikost pole jen na počet exportovaných obrázků
	if msgbox("Exportováno, nahrát?",20)<>6 then exit sub 'hláška že chci importovat

	rem IMPORT
	for i=ubound(p()) to lbound(p()) step -1
		oBunka=p(i)(0) 'buňka do které se vloží obrázek
		sUrl=p(i)(1) 'url obrázku
		oDrawPage=p(i)(2) 'drawPage původního obrázku
		oImg=oDoc.createInstance("com.sun.star.drawing.GraphicObjectShape") 'vytvořit grafický objekt obrázku
		oImg.GraphicURL=sUrl 'url obrázku do grafického objektu
		oDrawPage.add(oImg) 'přidat do stránky
		oSize=oImg.Graphic.Size100thMM 'originální rozměry obrázku
		oSize.width=CLng(oSize.width*iKoef) 'vynásobit šířku obrázku koeficientem
		oSize.height=CLng(oSize.height*iKoef) 'vynásobit výšku obrázku koeficientem
		oImg.Size=oSize 'nastavit orig. rozměry
		oImg.Anchor=oBunka 'ukotvit k požadované buňce
		rem zde kdyžtak bude změna výšky buňky dle obrázku
	next i
	exit sub
chyba:
	msgbox ("Chyba!" & chr(13) & "kód: " & Err & chr(13) & Error & chr(13) & "řádek: " & Erl,16)
End Sub

Offline

#28 25. 2. 2020 19:32:16

kamlan
Člen
Registrace: 15. 9. 2016
Příspěvků: 368

Re: Hromadná komprimace fotografii

Ještě mě napadlo, že pokud umíte/zjistíteJak zadat příkaz do Shellu který zkomprimuje obrázek, tak by se v makru dal využít příkaz Basicu Shell. Tím by to mohlo být bezzásahové tzn. odpadlo by dávkové zpracování těch exportovaných obrázků. Prostě by to automaticky komprimovalo nějakým externím programem namísto tím Libre komprimátorem který je teď obcházen ručně a import probíhá až po potvrzovací hlášce.

Offline

#29 26. 2. 2020 08:43:58

barevnej
Člen
Registrace: 6. 8. 2015
Příspěvků: 171

Re: Hromadná komprimace fotografii

Bohůžel tam je něco špatně. :-(
https://b2bware.eu/Video_01.mp4

Offline

#30 26. 2. 2020 13:02:35

kamlan
Člen
Registrace: 15. 9. 2016
Příspěvků: 368

Re: Hromadná komprimace fotografii

Je možné že tam ty obrázky máte ukotvené ke stránce a nikoliv k buňce. V takovém případě mi je to naimportovalo též, ale všechny do buňky A1, což není z videa vidět. Do buňky K10 vám to jeden malý obrázek zdá se importovalo, takže ten mohl být ukotven jako jediný k buňce.


Teď to testuje ukotvení obrázku ke stránce a nabídne ho překotvit k buňce, přičemž při souhlasu ho rovnou exportuje. Nevýhoda je že to zobrazí dotaz pro každý obrázek. Zde by byly možnosti: "Překotvit aktuální - Překotvovat již všechny - Nechat aktuální - Nechat již všechny". Jenže Libre nenabízí 4-tlačítkový dialog, což by znamenalo ho buď udělat (=pracnější a v nejbližších dnech se tomu věnovat nechci, resp. někdy fakt možná bych to udělal) nebo mít postupně více dotazů (=víc kombinací a tudíž vopruz s inklinací k chybám). Nejjednodušší by tedy bylo prostě do kódu natvrdo zabudovat třeba vždy překotvení k buňce, případně udělat samostatné makro pro automatické překotvení všech obrázků k buňce a až po  kontrole jak překotvil by se dal export/import.


Rozlišuje též JPG/PNG/GIF a dle toho exportuje (při nejasnostech do JPG).

Občas se mi taky stalo (pro GIFy) že se importovaly jako fakt miniprťavé, nenastavila se pro ně vlastnost oImg.Graphic.Size100thMM, což je ošetřené tak, že se vemou rozměry z oImg.Graphic.SizePixel a vynásobí se koeficientem který jsem spočetl z rozměrů jednoho PNG.


Taky kontroluje název obrázku a kdyžtak ho pojmenuje - to aby neexportoval jen nepojmenovaný soubor .jpg. Ono to nejspíš nenastane, ale stalo se mi že nebyly obrázky pojmenované (Název obrázku čili proměnná oImg.name byl prázdný u všech obrázků) snad po nějakém CtrlCV.

Sub EXPORT_IMPORT_OBRAZKU 'exportuje ze Sešitu obrázky do adresáře Sešitu a po odsouhlasení hlášky importuje ony obrázky - před potvrzením hlášky se dají tedy upravit
	'on local error resume next 'při chybě pokračovat dál
	on local error goto chyba 'při chybě jít na návěští chyba
	const cKoef as double=2/3 'koeficient kterým se vynásobí rozměry obrázku
	const cNazev$="HoltNepojmenovan" 'výchozí název obrázků když nejsou v Sešitě pojmenované, měl by být pokud možno originální aby se to netrefilo do nějakého již použitého jména
	const cLom$="/" 'lomítko do url
	dim oDoc, oGP, p(1000000), i&, s$, pUrl(), oList, oImg, n&, oDrawPage, oBunka, sUrl$, oCur, oSize as object, oPos,sMime$, iStr&, iPrek&
	dim props(1) as new com.sun.star.beans.PropertyValue
	props(0).Name="URL" : props(1).Name="MimeType"
	oDoc=thisComponent 'aktuální Sešit
	
	rem EXPORT
	pUrl=split(oDoc.URL, cLom) 'pole pro url se jménem dokumentu
	oGP=createUnoService("com.sun.star.graphic.GraphicProvider") 'objekt grafické služby
	i=0 : iStr=0 : iPrek=0 'kolik obrázků exportuje z dokumentu : kolik obrázků je ukotvených ke stránce : kolik jich bylo překotveno k buňce
	for each oList in oDoc.Sheets 'pro každý list
		oDrawPage=oList.DrawPage 'grafické objekty listu
		for n=oDrawpage.Count-1 to 0 step -1 'projet všechny graf. objekty
			oImg=oDrawpage.getByIndex(n) 'vybraný grafický objekt
			if oImg.supportsService("com.sun.star.drawing.GraphicObjectShape") then 'jde o obrázek
				if NOT oImg.Anchor.supportsService("com.sun.star.sheet.SheetCell") then 'nejde o ukotvení k buňce
					iStr=iStr+1 'počet obrázků ukotvených ke stránce
					oDoc.currentController.select(oImg) 'označit obrázek
					if msgbox("Nebude-li obrázek překotven k buňce, bude ignorován." & chr(13) & chr(13) & "Překotvit k buňce?",36,"Obrázek je ukotven ke stránce")=6 then
						uno("SetAnchorToCell",oDoc) 'překotvit k buňce
						iPrek=iPrek+1 'počet překotvených k buňce
					else
						uno("Deselect") 'odznačit obrázek
						goto preskok 'při nepřekotvení přeskočit obrázek
					end if
					uno("Deselect") 'odznačit obrázek
				end if
				s=oImg.name 'jméno obrázku
				if s="" then
					s=cNazev & i 'když je prázdné jméno obrázku tak nastavit výchozí
					oImg.name=s 'pojmenovat obrázek výchozím jménem
				end if
				sMime=oImg.Graphic.MimeType 'mimetype obrázku
				pUrl(ubound(pUrl))=oImg.name & priponaDleMime(sMime) 'poslední položka v poli je jméno Sešitu, to nahradí jménem obrázku s příponou
				props(0).Value=convertToURL(join(pUrl, cLom)) : props(1).Value=sMime 'url a MimeType obrázku
				oGP.storeGraphic(oImg.Graphic, props) 'uložit obrázek
				sUrl=join(pUrl,cLom) 'url obrázku
				p(i)=array(oImg.Anchor,sUrl,oDrawPage,s) 'pole s buňkou, url příslušného obrázku, příslušný DrawPage a jméno obrázku
				oDrawpage.remove(oImg) 'odstranit obrázek
				i=i+1 'počet exportovaných obrázků
		preskok:
			end if
		next n
	next oList
	if i=0 then
		msgbox("Nebyl exportován žádný obrázek",48)
		exit sub
	end if
	redim preserve p(i-1) 'velikost pole jen na počet exportovaných obrázků
	if msgbox(iif(iStr>0,"Ke stránce bylo ukotveno obrázků: " & iStr & chr(13) & "Z nich překotveno k buňce: " & iPrek & chr(13) & chr(13),"") & "Exportováno, nahrát?",20)<>6 then exit sub 'hláška že chci importovat

	rem IMPORT
	for i=ubound(p()) to lbound(p()) step -1
		oBunka=p(i)(0) 'buňka do které se vloží obrázek
		sUrl=p(i)(1) 'url obrázku
		oDrawPage=p(i)(2) 'drawPage původního obrázku
		s=p(i)(3) 'jméno obrázku
		oImg=oDoc.createInstance("com.sun.star.drawing.GraphicObjectShape") 'vytvořit grafický objekt obrázku
		oImg.GraphicURL=sUrl 'url obrázku do grafického objektu
		oDrawPage.add(oImg) 'přidat do stránky
		oSize=oImg.Graphic.Size100thMM 'originální rozměry obrázku
		if oSize.width=0 OR oSize.height=0 then 'žádné rozměry pro setinu milimetru, to mi udělal pro GIF
			dim const c100thMM as double=35.28 'konstanta pro přepočet na setiny milimetru
			oSize.width=CLng(oImg.graphic.sizePixel.width*c100thMM)
			oSize.height=CLng(oImg.graphic.sizePixel.height*c100thMM)
		end if
		oSize.width=CLng(oSize.width*cKoef) 'vynásobit šířku obrázku koeficientem
		oSize.height=CLng(oSize.height*cKoef) 'vynásobit výšku obrázku koeficientem
		oImg.Size=oSize 'nastavit orig. rozměry
		oImg.name=s 'nastavit původní jméno obrázku
		oImg.Anchor=oBunka 'ukotvit k požadované buňce
	next i
	exit sub
chyba:
	msgbox ("Chyba!" & chr(13) & "kód: " & Err & chr(13) & Error & chr(13) & "řádek: " & Erl,16)
End Sub

Function priponaDleMime(sMime$) as string 'vrátí příponu souboru na základě MimeType z com.sun.star.graphic.GraphicDescriptor.MimeType
	dim s$
	select case sMime
		case "image/jpeg"
			s="jpg"
		case "image/png"
			s="png"
		case "image/gif"
			s="gif"
		case else 'jako výchozí JPG
			s="jpg"
	End select
	priponaDleMime="." & s
End Function

Sub uno(s$, optional oDoc as object) 'provede uno příkaz
	if isMissing(oDoc) then oDoc=thisComponent
	s=".uno:" & s 'jaký uno příkaz
	createUnoService("com.sun.star.frame.DispatchHelper").executeDispatch(oDoc.CurrentController.Frame, s, "", 0, array()) 'provést
End Sub

Offline

#31 26. 2. 2020 13:27:57

barevnej
Člen
Registrace: 6. 8. 2015
Příspěvků: 171

Re: Hromadná komprimace fotografii

Zatím tato poslední verze funguje nejlépe, první obrázek mi to sice udělá miniaturní ale musím zkusit v reálu jak moc se tato chyba projeví, možná že všechny fotky budou klasické jpg nebo png a nebude to problém. Jinak je to fakt dobré. Skoro je to na nějaké zveřejnění jelikož si myslím že tohle by ocenilo hromada lidí. Jste fakt dobrej. Děkuji mnohokrát.

Offline

#32 26. 2. 2020 14:02:02

kamlan
Člen
Registrace: 15. 9. 2016
Příspěvků: 368

Re: Hromadná komprimace fotografii

Když vám to bude zmenšovat všechny obrázky, tak si zvětšete konstantu cKoef a namísto 2/3 dejte třeba 1. Já to prostě udělal podle toho jak to chodí u mě.

Offline

Zápatí