Skocz do zawartości

screen_save_part jak usunąć czarne tło i poprawnie skalować?


MetalowyNerd

Rekomendowane odpowiedzi

Siema 🖖. Próbuję zrobić mały programik, który zapisuje fragment wybranego obszaru z podanych koordynatów i szerokości pola, jednak wymiary w roździelczościach się różnią, bo camera to 226x226 a viewport to 904x904 (viewport jest dokładnie 4x większy). I mam teraz dwa problemy.

 

1. Piksele w programie sa 4 razy większe (bo chcę, żeby użytkownik widział lepiej wygenerowany pixelart), jednak fragment zrzutu ekranu (czyli wybrany przeze mnie obszar) nie dososowuje się do tego rozmiaru i muszę ręcznie zwiększyć jego wielkość o 4x. To skutkuje 4x większym wygenerowanym obrazem, niż potrzeba. Chciałbym zmniejszyć wygenerowany obraz 4x, bo to pixelart, którego piksele mają być 4x większe tylko w podglądzie programu, a wygenerowane już obrazy powinny mieć piksele w skali 1, nie 4.

 

2. Wygenerowane obrazy albo nieposiadają kanału alpha i mają czarne tło, albo posiadają kanał alpha ale nadal mają czarne tło. Nie wiem, jak się tego tła pozbyć, żeby obrazy generowane z mojego programu miały już przezroczyste tło.

Odnośnik do komentarza
Udostępnij na innych stronach

Niestety nie działa. A w zasadzie działa identycznie co screen_save_part. Wpisuję surface_save_part(application_surface, dalej koordynaty i rozmiar...). Przezroczystości nie ma, bo tło obrazów nadal jest czarne, a rozdzielczość to 64x64, a powinna być 16x16 (4x większe piksele, a takie powinny być tylko w podglądzie w programie)

Odnośnik do komentarza
Udostępnij na innych stronach

  • Administratorzy

Jest jeszcze takie rozwiązanie - utworzyć surface, dać surface_set_target() przed pierwszym rysowanym elementem (czyli jakieś wysokie depth), oraz kolejny obiekt z surface_reset_target() z niskim depth i wtedy wyrenderujesz to co chcesz dokładnie na surface i będzie przeźroczyste tło. Żeby nie bawić się w przesuwanie koordynatów z 0,0 do miejsca które chcesz, możesz użyć camera_apply() - ale wtedy kamera na tę jedną klatkę musi zaczynać się tam, gdzie ma zaczynać się screen.

 

Będzie z tym troche zabawy, ale GM na pewno pozwala na generowanie przeźroczystych PNG, bo generowałem tak kiedyś stripy z fontem.

Odnośnik do komentarza
Udostępnij na innych stronach

surface_save_part nie działa wcale. Próbuję wywołać funkcję zapisu obrazu, nic żadnej reakcji, żaden plik nie powstaje :(. Program jest już trochę rozbudowany, dlatego trochę ciężko mi wrzucić tu kod, ale spróbuję.

 

W programie jest obiekt o_cursor, który jest zwyczajnie kursorem zawierającym kilka narzędzi do modyfikacji grafiki. W evencie Room Start:

global.DEFAULTSURFACE = surface_create(226, 226);

Jest też obiekt o_swordPreview, który służy do generowania wyglądu miecza 16x16 (w programie widoczne w powiększeniu przez viewport x4). W Draw:

surface_set_target(global.DEFAULTSURFACE);
draw_self();//tu wyświetla samą rękojeść
...// dalej wyświetla różne elementy przez funkcję draw_sprite_ext
surface_reset_target();

I jest obiekt o_block_base, który zapisuje obszar jako grafikę w postaci pliku. Draw GUI (bez znaczenia czy Draw GUI czy zwykły Draw):

surface_set_target(global.DEFAULTSURFACE);
... tu jest ustalenie daty i formatu jej zapisywania żeby nazwa pliku ją zawierała dla porządku
var mult = 4;//niestety muszę mnożyć wielkość zapisywanego obszaru x4, bo inaczej obejmie tylko mały fragment miecza a nie całość...
screen_save_part("swords "+string(date_get_day(date_current_datetime()))+"-"+string(monthFix)+"-"+string(date_get_year(date_current_datetime()))+"/sword_" + string(name) + ".png", (o_swordPreview.x - 8)*mult, (o_swordPreview.y - 8)*mult, (16*mult), (16*mult));

surface_reset_target();

Sporo zabawy a nadal nie działa. Teraz nawet nie zapisuje obrazu do pliku. Pamiętam, że kilka lat temu jakoś udało mi się to zrobić bez surface'ów, w sensie przezroczyste tło, tylko nie pamiętam, jak to zrobiłem, a użyłem screen_save_part wtedy. Podejrzewam, że surface'ów nie zapisuje się globalami, ale bez globala o_block_base wypluwa błąd, że DEFAULTSURFACE nie zostało zadeklarowane. A zostało, tylko w o_cursor. Ewentualnie zamiast global.DEFAULTSURFACE mogę użyć o_cursor.DEFAULTSURFACE... tylko czy to zadziała, moment sprawdzę

Odnośnik do komentarza
Udostępnij na innych stronach

  • Administratorzy
5 godzin temu, MetalowyNerd napisał:

Podejrzewam, że surface'ów nie zapisuje się globalami

można, jak najbardziej.

 

Surface zapewne zapisuje się w "%LOCALAPPDATA%/NazwaGry".

Odnośnik do komentarza
Udostępnij na innych stronach

Jeśli chcesz dodać odpowiedź, zaloguj się lub zarejestruj nowe konto

Jedynie zarejestrowani użytkownicy mogą komentować zawartość tej strony.

Zarejestruj nowe konto

Załóż nowe konto. To bardzo proste!

Zarejestruj się

Zaloguj się

Posiadasz już konto? Zaloguj się poniżej.

Zaloguj się
  • Ostatnio przeglądający   0 użytkowników

    • Brak zarejestrowanych użytkowników przeglądających tę stronę.
×
×
  • Dodaj nową pozycję...