Forum » Programiranje » [Pillow] Kako shranit PNG (mode P) sliko v JPEG?
[Pillow] Kako shranit PNG (mode P) sliko v JPEG?

HotBurek ::
Dobro zgodnje jutro.
Evo, fantje in dekline, nov dan, nov izziv.
Source image je tole:
Zdej me pa zanima, kako konvertat to sliko v jpeg format, in to tako, da tist "transparenten" background okrog konzerve ne postane zelen (ali črn)?
Trenutni sample:
Če grem plan a, dobim na output-u warning:
UserWarning: Palette images with Transparency expressed in bytes should be converted to RGBA images
Print:
image mode [1]: P
image format [1]: PNG
image mode [2]: RGB
image format [2]: None
In končno sliko:
Če grem plan b, dobim na output-u error:
OSError: cannot write mode RGBA as JPEG
Print:
image mode [1]: P
image format [1]: PNG
image mode [2]: RGBA
image format [2]: None
Že od prej imam link na tole: PIL remove error "UserWarning: Palette images with Transparency expressed in bytes should be converted to RGBA images"
No, zdej moram to nekako rešit. Kako PNG sliko, ki je v mode P, shranit v JPEG format? Pa da bo lepo zgledalo, kot na izvoru.
Evo, fantje in dekline, nov dan, nov izziv.
Source image je tole:
Zdej me pa zanima, kako konvertat to sliko v jpeg format, in to tako, da tist "transparenten" background okrog konzerve ne postane zelen (ali črn)?
Trenutni sample:
import io; import PIL.Image; image = PIL.Image.open("/home/sepultura/arise/minerva_in.png"); print("image mode [1]: " + str(image.mode)); print("image format [1]: " + str(image.format)); plan = "a"; if image.mode in ["1", "8", "L", "P", "CMYK", "RGBA", "LA"]: # plan a if plan == "a": image = image.convert("RGB"); # plan b elif plan == "b": if image.format == "PNG": image = image.convert("RGBA"); else: image = image.convert("RGB"); print("image mode [2]: " + str(image.mode)); print("image format [2]: " + str(image.format)); image.save("/home/sepultura/arise/minerva_out.jpeg", format="JPEG", optimize=True); image.close();
Če grem plan a, dobim na output-u warning:
UserWarning: Palette images with Transparency expressed in bytes should be converted to RGBA images
Print:
image mode [1]: P
image format [1]: PNG
image mode [2]: RGB
image format [2]: None
In končno sliko:
Če grem plan b, dobim na output-u error:
OSError: cannot write mode RGBA as JPEG
Print:
image mode [1]: P
image format [1]: PNG
image mode [2]: RGBA
image format [2]: None
Že od prej imam link na tole: PIL remove error "UserWarning: Palette images with Transparency expressed in bytes should be converted to RGBA images"
No, zdej moram to nekako rešit. Kako PNG sliko, ki je v mode P, shranit v JPEG format? Pa da bo lepo zgledalo, kot na izvoru.
root@debian:/# iptraf-ng
fatal: This program requires a screen size of at least 80 columns by 24 lines
Please resize your window
fatal: This program requires a screen size of at least 80 columns by 24 lines
Please resize your window
- spremenilo: HotBurek ()

socialec ::
jpeg podpira transparenco?
kolikor vidim, hitri queryji pravijo, da ne...
menda je rešitev, da zmergaš na fiksen background image
kolikor vidim, hitri queryji pravijo, da ne...
menda je rešitev, da zmergaš na fiksen background image

Liker ::
if image.format == "PNG": image = image.convert("RGBA"); bg = Image.new('RGBA', image.size, (0, 155, 0, 0)) final_image = Image.alpha_composite(bg,image) ...
No comment ...


HotBurek ::
Tvoj sample ne dela, ker:
Delujočo rešitev sem našel tule:
How to Covert PNG to JPEG using Pillow while image color is black?
To z "background" rešitvijo že imam za resize. Zdej pa še za PNG P situacijo. Moram dodelat še, da RGBA konverta v RGB, ter LA v L.
OSError: cannot write mode RGBA as JPEG
Delujočo rešitev sem našel tule:
How to Covert PNG to JPEG using Pillow while image color is black?
To z "background" rešitvijo že imam za resize. Zdej pa še za PNG P situacijo. Moram dodelat še, da RGBA konverta v RGB, ter LA v L.
root@debian:/# iptraf-ng
fatal: This program requires a screen size of at least 80 columns by 24 lines
Please resize your window
fatal: This program requires a screen size of at least 80 columns by 24 lines
Please resize your window
Zgodovina sprememb…
- spremenilo: HotBurek ()

cekr ::
Uporabljaj raje TIFF.
Sinclair ZX Spectrum [Zilog Z80A - 3.5 MHz, 48kB, dvojni kasetofon,
TV-OUT, radirke, Sinclair-Basic], Sinclair ZX-81 [Z80A, 3.25MHZ, 1kB]
TV-OUT, radirke, Sinclair-Basic], Sinclair ZX-81 [Z80A, 3.25MHZ, 1kB]

no comment ::
Nekateri formati se uporabljajo z razlogom. Če moraš imeti tranparency oz. alpha layer, izbereš ustrezen format.

Liker ::
*sigh*
Sem prebral, da želiš zeleno ozadje. JPEG ne podpira prosojnosti, saj to veš, ne?
In moja koda ni bila popolna. Če želiš shraniti JPEG, moraš najprej narediti nazaj convert v RGB mode. Na primer:
To naredi JPG z belim ozadjem, kar si si verjetno želel.
Je pa python koda s podpičji res zakon. Thumbs up!
Sem prebral, da želiš zeleno ozadje. JPEG ne podpira prosojnosti, saj to veš, ne?
In moja koda ni bila popolna. Če želiš shraniti JPEG, moraš najprej narediti nazaj convert v RGB mode. Na primer:
>>> from PIL import Image >>> img = Image.open("Minerva-in.png") >>> img = img.convert("RGBA") >>> bg = Image.new("RGBA",img.size,(255,255,255,255)) >>> end = Image.alpha_composite(bg,img) >>> end_jpg = end.convert("RGB") >>> end_jpg.save("Minerva-out.jpeg")
To naredi JPG z belim ozadjem, kar si si verjetno želel.
Je pa python koda s podpičji res zakon. Thumbs up!

HotBurek ::
Ja ja, to. Da se transparentnost iz PNG zamenja v belo "ozadje" pri shranjevanju v JPEG.
Takole imam sedaj. Sem potestiral in dela, kot je željeno. Verjamem pa, da so še tudi druge/drugačne rešitve.
Takole imam sedaj. Sem potestiral in dela, kot je željeno. Verjamem pa, da so še tudi druge/drugačne rešitve.
# UserWarning: Palette images with Transparency expressed in bytes should be converted to RGBA images # https://stackoverflow.com/questions/70839890/pil-remove-error-userwarning-palette-images-with-transparency-expressed-in-byt if image.format == "PNG": # set new mode for background new_mode = "RGB"; # check if this is LA if image.mode == "LA": # set new mode to L new_mode = "L"; # logging logging(loginfo, "PIL > new_mode: " + str(new_mode)); # logging logging(loginfo, "PIL > Convert image from " + str(image.mode) + " mode to RGBA"); # convert image from x to RGBA image = image.convert("RGBA"); # make white background background = PIL.Image.new(new_mode, (image.width, image.height), (255, 255, 255)); # put all together # https://stackoverflow.com/questions/50739732/how-to-covert-png-to-jpeg-using-pillow-while-image-color-is-black background.paste(image, image); # save back as image image = background;
root@debian:/# iptraf-ng
fatal: This program requires a screen size of at least 80 columns by 24 lines
Please resize your window
fatal: This program requires a screen size of at least 80 columns by 24 lines
Please resize your window
Zgodovina sprememb…
- spremenilo: HotBurek ()

HotBurek ::
Dobro jutro.
Evo, update. Zadevo sem še mel dodelal, ker sem naletel na PNG v LA mode.
Tisti, ki bi želel potestirat, gre za tole sliko:
qs-favicon-32x32.png
Razlika je v barvi: pri RGB je (255, 255, 255), pri L pa 255.
Trenutni working sample je takšen:
Evo, update. Zadevo sem še mel dodelal, ker sem naletel na PNG v LA mode.
Tisti, ki bi želel potestirat, gre za tole sliko:
qs-favicon-32x32.png
Razlika je v barvi: pri RGB je (255, 255, 255), pri L pa 255.
Trenutni working sample je takšen:
if image.format in ["PNG", "ICO"]: if image.mode == "RGBA": new_mode = "RGB"; background = PIL.Image.new(new_mode, (image.width, image.height), (255, 255, 255)); background.paste(image, image); image = background; elif image.mode == "LA": new_mode = "L"; background = PIL.Image.new(new_mode, (image.width, image.height), 255); background.paste(image, image); image = background; else: image = image.convert("RGB");
root@debian:/# iptraf-ng
fatal: This program requires a screen size of at least 80 columns by 24 lines
Please resize your window
fatal: This program requires a screen size of at least 80 columns by 24 lines
Please resize your window
Zgodovina sprememb…
- spremenilo: HotBurek ()

HotBurek ::
Me pa ena reč en mal, a kvalitetno, matra.
Spodnji ukaz ne znam prestavit v karkoli drugega, da bi bilo meni bolj razumljivo in da bi zadevo razumel:
Skratka, ta drugi parameter (image, image) mi ni jasen, kako bi ga "pretvoril" v nekaj drugega (koordinate in /ali mask). Tako, da bi bilo vsaj meni bolj jasno kaj drugi parameter "vnaša" (koordinate, mask, ???).
Spodnji ukaz ne znam prestavit v karkoli drugega, da bi bilo meni bolj razumljivo in da bi zadevo razumel:
# dela kot je treba background.paste(image, image); # naredi črno sliko (iz zgornjega LA primera) background.paste(image, (0, 0)); background.paste(image, (0, 0, image.width, image.height)); background.paste(image, (0, 0), 0); background.paste(image, (0, 0), "L");
Skratka, ta drugi parameter (image, image) mi ni jasen, kako bi ga "pretvoril" v nekaj drugega (koordinate in /ali mask). Tako, da bi bilo vsaj meni bolj jasno kaj drugi parameter "vnaša" (koordinate, mask, ???).
root@debian:/# iptraf-ng
fatal: This program requires a screen size of at least 80 columns by 24 lines
Please resize your window
fatal: This program requires a screen size of at least 80 columns by 24 lines
Please resize your window
Zgodovina sprememb…
- spremenilo: HotBurek ()

socialec ::
background.paste(image, image) pomeni: prilepi image na background, ampak upoštevaj alfa kanal iz image, da ohraniš prosojnost.

HotBurek ::
Takole imam končno verzijo:
Več pa ne bom zdej kompliciral z mask-om.
Zdejle sem imel 2 ure in 40 minut tegale: 5 hours Set: From TECHNO to HARDTECHNO w/ Fernanda Martins SPAIN JUL/2016
Vem vem, pussz, ker nisem zdržal celih 5 ur.
Pa še neki sem parser vmes pofiksal. Fak d fakin šiiiit... Greeeemoooo. Lets go!
Zdej bo treba dat volume dol, da se bo slišal cerkev zvonit... ker bo ura vsak cajt ... upugn.
background.paste(image, (0, 0), image);
Več pa ne bom zdej kompliciral z mask-om.
Zdejle sem imel 2 ure in 40 minut tegale: 5 hours Set: From TECHNO to HARDTECHNO w/ Fernanda Martins SPAIN JUL/2016
Vem vem, pussz, ker nisem zdržal celih 5 ur.
Pa še neki sem parser vmes pofiksal. Fak d fakin šiiiit... Greeeemoooo. Lets go!
Zdej bo treba dat volume dol, da se bo slišal cerkev zvonit... ker bo ura vsak cajt ... upugn.

root@debian:/# iptraf-ng
fatal: This program requires a screen size of at least 80 columns by 24 lines
Please resize your window
fatal: This program requires a screen size of at least 80 columns by 24 lines
Please resize your window
Zgodovina sprememb…
- spremenilo: HotBurek ()

HotBurek ::
Evo, naslednji primer.
Izvorna slika v formatu PNG, mode I (32-bit signed integer pixels).
Tule je seznam: https://pillow.readthedocs.io/en/stable...
Kako to skonvertat v JPEG?
Dodal sem mode I, delam po zgornjem primeru, in na koncu dobim belo sliko.
Krneki...
Slika:
Izvorna slika v formatu PNG, mode I (32-bit signed integer pixels).
Tule je seznam: https://pillow.readthedocs.io/en/stable...
Kako to skonvertat v JPEG?
Dodal sem mode I, delam po zgornjem primeru, in na koncu dobim belo sliko.
Krneki...
Slika:
root@debian:/# iptraf-ng
fatal: This program requires a screen size of at least 80 columns by 24 lines
Please resize your window
fatal: This program requires a screen size of at least 80 columns by 24 lines
Please resize your window
Zgodovina sprememb…
- spremenilo: HotBurek ()

Liker ::
Evo, naslednja rešitev.
Tvoj primer ni 32 biten PNG, ampak 16 biten.
PIL je imel bug, kjer je to napačno javljal.
Verjetno boš potreboval novejšo verzijo PIL knjižnice, če pa ne gre, si pa poglej PR iz linka in implementiraj workaround.
Tvoj primer ni 32 biten PNG, ampak 16 biten.
kavcar@biric:~$ file coltello.png coltello.png: PNG image data, 596 x 768, 16-bit grayscale, non-interlaced kavcar@biric:~$
PIL je imel bug, kjer je to napačno javljal.
Verjetno boš potreboval novejšo verzijo PIL knjižnice, če pa ne gre, si pa poglej PR iz linka in implementiraj workaround.

HotBurek ::
Ok, hvala za info.
Kot omenjeno, se zadeva dogaja v:
Fajl: /usr/lib/python3/dist-packages/PIL/PngImagePlugin.py
Linija: 65
Cotntent:
Jst sem malenkost telovadil (označil zgoraj), ampak je tole ... hm... mogoče izven okvirja mojih zmožnosti.
Na srečo je do sedaj od miljon slik tole bil prvi, in zaenkrat, tudi edini tak primer.
Kot omenjeno, se zadeva dogaja v:
Fajl: /usr/lib/python3/dist-packages/PIL/PngImagePlugin.py
Linija: 65
Cotntent:
_MODES = { # supported bits/color combinations, and corresponding modes/rawmodes # Greyscale (1, 0): ("1", "1"), (2, 0): ("L", "L;2"), (4, 0): ("L", "L;4"), (8, 0): ("L", "L"), >>> #(16, 0): ("I", "I;16B"), (16, 0): ("I;16B", "I;16B"), # Truecolour (8, 2): ("RGB", "RGB"), (16, 2): ("RGB", "RGB;16B"), # Indexed-colour (1, 3): ("P", "P;1"), (2, 3): ("P", "P;2"), (4, 3): ("P", "P;4"), (8, 3): ("P", "P"), # Greyscale with alpha (8, 4): ("LA", "LA"), (16, 4): ("RGBA", "LA;16B"), # LA;16B->LA not yet available # Truecolour with alpha (8, 6): ("RGBA", "RGBA"), (16, 6): ("RGBA", "RGBA;16B"), }
Jst sem malenkost telovadil (označil zgoraj), ampak je tole ... hm... mogoče izven okvirja mojih zmožnosti.
Na srečo je do sedaj od miljon slik tole bil prvi, in zaenkrat, tudi edini tak primer.
root@debian:/# iptraf-ng
fatal: This program requires a screen size of at least 80 columns by 24 lines
Please resize your window
fatal: This program requires a screen size of at least 80 columns by 24 lines
Please resize your window
Zgodovina sprememb…
- spremenilo: HotBurek ()

Liker ::
Ja, morda ni najlažje za popravit knjižnico, ni panike.
Obstaja workaround, ki ga ti dejansko lahko implementiraš, ker imaš itak if za vsak PNG mode ločeno.
Torej rabiš nekaj takega:
To bi moralo delovati, rabiš pa seveda še "import subprocess" in pa "import numpy".
Obstaja workaround, ki ga ti dejansko lahko implementiraš, ker imaš itak if za vsak PNG mode ločeno.
Torej rabiš nekaj takega:
if img.mode == "I": if "16-bit" in subprocess.check_output(["file",path_to_file]): max_value = 2**16 - 1 img_arr = (numpy.array(img) / max_value) * 255.0 img = Image.fromarray(img_arr.astype(numpy.uint8)) img = img.convert("RGBA") ...
To bi moralo delovati, rabiš pa seveda še "import subprocess" in pa "import numpy".

HotBurek ::
Ful kul debest žur. Zadeva dela v nulo, zato bom lepo dal eno večerno sliko na ogled.
Dodal sem sicer eno malenkost. In to je, da se vsebino, ki jo vrne subprocesa, konverta iz byte v string. Ostalo pa je isto.
Je pa situacija taka, da trenutno verjetno zadeve še ne bom čisto končal.
Tisto, kar me je zmatral, je to, da subprocess za ta drugi input vzame pot_do_slike, jst pa izvorne slike (to govorim na serverju) nikoli ne shranim na disk (ostane v RAM-u, pol gre pa ven).
Tu moram še dodelat, da bo, v kolikor bo šel v tist "if I", da bo sliko shranil nekam na disk, in potem naredil subprocess ukaz. Ter, da bo to izvorno slikov v temp-u potem tudi zbrisal.
Sicer pa ja, it works. Hvala za input.
Dodal sem sicer eno malenkost. In to je, da se vsebino, ki jo vrne subprocesa, konverta iz byte v string. Ostalo pa je isto.
Je pa situacija taka, da trenutno verjetno zadeve še ne bom čisto končal.
Tisto, kar me je zmatral, je to, da subprocess za ta drugi input vzame pot_do_slike, jst pa izvorne slike (to govorim na serverju) nikoli ne shranim na disk (ostane v RAM-u, pol gre pa ven).
Tu moram še dodelat, da bo, v kolikor bo šel v tist "if I", da bo sliko shranil nekam na disk, in potem naredil subprocess ukaz. Ter, da bo to izvorno slikov v temp-u potem tudi zbrisal.
Sicer pa ja, it works. Hvala za input.

root@debian:/# iptraf-ng
fatal: This program requires a screen size of at least 80 columns by 24 lines
Please resize your window
fatal: This program requires a screen size of at least 80 columns by 24 lines
Please resize your window
Zgodovina sprememb…
- spremenilo: HotBurek ()

Liker ::
Če imaš png že v "ramu", potem lahko pogledaš vrednost byta na offsetu 24 - tam notru je zapisan bit_depth direktno.
>>> f = open("coltello.png","rb") >>> img_data = f.read() >>> img_data[24] 16 >>>

HotBurek ::
In to je sedaj končna rešitev.
"content" pride iz:
import requests;
response = requests.get(url, ...);
content = response.content;
"content" pride iz:
import requests;
response = requests.get(url, ...);
content = response.content;
# this is some nasty fix for I;16 images and the way python handles this stuff # https://github.com/python-pillow/Pillow/issues/3796 if image.format == "PNG" and image.mode == "I": # init bit depth bit_depth = 0; # check if content length is at least 25 if len(content) > 24: # read byte at position 24 where bit depth value is bit_depth = content[24]; # logging logging(loginfo, "PIL > bit_depth=" + str(bit_depth)); # check if bit depth is 16 if bit_depth == 16: # some magic i dont know how it works... but it does max_value = 2 ** 16 - 1; img_arr = (numpy.array(image) / max_value) * 255.0; image = PIL.Image.fromarray(img_arr.astype(numpy.uint8)); image = image.convert("RGBA");
root@debian:/# iptraf-ng
fatal: This program requires a screen size of at least 80 columns by 24 lines
Please resize your window
fatal: This program requires a screen size of at least 80 columns by 24 lines
Please resize your window
Vredno ogleda ...
Tema | Ogledi | Zadnje sporočilo | |
---|---|---|---|
Tema | Ogledi | Zadnje sporočilo | |
» | [Python] PIL.Image resize in slaba kvalitetaOddelek: Programiranje | 723 (516) | DamijanD |
» | CSS3 - Transparentnost + Text ProblemOddelek: Izdelava spletišč | 940 (769) | Tydek |
» | uporaba C++ unmanaged kode v C#.NET projektuOddelek: Programiranje | 2010 (1733) | krho |
» | image/png .......(prikaz!!)?Oddelek: Izdelava spletišč | 1245 (1136) | Ziga Dolhar |
» | [java] transparentnostOddelek: Programiranje | 1298 (1072) | jpzoky1 |