ΠΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ°, ΠΊΠΎΡΠΎΡΠ°Ρ ΠΏΡΠ΅Π²ΡΠ°ΡΠ°Π΅Ρ ΠΌΠΎΠ΄Π΅Π»ΠΈ Sacred Gold ΠΈΠ· Granny 1.2 (.grn) Π²
Π±ΠΈΠ½Π°ΡΠ½ΡΠΉ glTF (.glb) ΠΏΡΡΠΌΠΎ Π² ΠΏΠ°ΠΌΡΡΠΈ. ΠΠ½Π° Π½ΡΠΆΠ½Π° ΠΌΠΎΠ΄Π°ΠΌ, ΠΊΠΎΡΠΎΡΡΠ΅ ΠΏΠΎΠΊΠ°Π·ΡΠ²Π°ΡΡ
ΠΌΠΎΠ΄Π΅Π»ΠΈ ΠΈΠ³ΡΡ, ΠΈ ΡΠ΅ΠΌ, ΠΊΡΠΎ ΡΠ°Π±ΠΎΡΠ°Π΅Ρ Π½Π°Π΄ Π·Π°Π³ΡΡΠ·ΡΠΈΠΊΠΎΠΌ.
ΠΡ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΡΠ΅ Π±Π°ΠΉΡΡ ΠΌΠΎΠ΄Π΅Π»ΠΈ ΠΈ ΠΏΠΎΠ»ΡΡΠ°Π΅ΡΠ΅ Π±Π°ΠΉΡΡ GLB: ΠΌΠ΅ΡΠΈ, ΡΠΊΠ΅Π»Π΅Ρ, Π²Π΅ΡΠ° ΡΠΊΠΈΠ½Π½ΠΈΠ½Π³Π°, ΠΌΠ°ΡΠ΅ΡΠΈΠ°Π»Ρ ΠΈ ΡΠ΅ΠΊΡΡΡΡΡ Π² PNG Π²Π½ΡΡΡΠΈ ΡΠ°ΠΉΠ»Π°. Π€Π°ΠΉΠ»ΠΎΠ² Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ° Π½Π΅ ΡΠΈΡΠ°Π΅Ρ ΠΈ Π½Π΅ ΠΏΠΈΡΠ΅Ρ, ΡΠ°ΠΊ ΡΡΠΎ ΠΌΠΎΠ΄ ΡΠ°ΠΌ ΡΠ΅ΡΠ°Π΅Ρ, ΠΎΡΠΊΡΠ΄Π° Π²Π·ΡΡΡ ΠΌΠΎΠ΄Π΅Π»Ρ ΠΈ ΠΊΡΠ΄Π° ΠΏΠΎΠ»ΠΎΠΆΠΈΡΡ ΡΠ΅Π·ΡΠ»ΡΡΠ°Ρ.
ΠΠΎΠ»ΡΡΠΈΠ½ΡΡΠ²ΠΎ ΡΠ΅ΠΊΡΡΡΡ Sacred Ρ ΡΠ°Π½ΠΈΡ Π½Π΅ Π² ΠΌΠΎΠ΄Π΅Π»ΠΈ, Π° ΠΎΡΠ΄Π΅Π»ΡΠ½ΡΠΌΠΈ ΡΠ°ΠΉΠ»Π°ΠΌΠΈ. ΠΠ»Ρ ΡΠ°ΠΊΠΈΡ ΡΠ»ΠΎΡΠΎΠ² Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ° Π½Π°Π·ΡΠ²Π°Π΅Ρ ΠΈΠΌΡ ΡΠ°ΠΉΠ»Π°, Π° ΠΏΠΈΠΊΡΠ΅Π»ΠΈ RGBA ΠΏΡΠΈΡΡΠ»Π°Π΅ΡΠ΅ Π²Ρ. ΠΡΡΡΠΎΠ΅Π½Π½ΡΠ΅ ΡΠ΅ΠΊΡΡΡΡΡ, ΡΡΡΡΠ΅ ΠΈ ΡΠΆΠ°ΡΡΠ΅ VTex, ΠΎΠ½Π° Π΄Π΅ΠΊΠΎΠ΄ΠΈΡΡΠ΅Ρ ΡΠ°ΠΌΠ°.
grn2glb.dll β 64-Π±ΠΈΡΠ½Π°Ρ DLL Ρ ΠΏΡΠΎΡΡΡΠΌ C ABI. Java 22 ΠΈ Π½ΠΎΠ²Π΅Π΅ Π²ΡΠ·ΡΠ²Π°Π΅Ρ Π΅Ρ
ΡΠ΅ΡΠ΅Π· FFM (Panama) Π±Π΅Π· JNI. CRT ΡΠΎΠ±ΡΠ°Π½ ΡΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΈ, ΠΏΠΎΡΡΠΎΠΌΡ ΠΈΠ³ΡΠΎΠΊΡ Π½Π΅ Π½ΡΠΆΠ΅Π½
VC++ Redistributable.
-
Π‘ΠΎΠ±Π΅ΡΠΈΡΠ΅
grn2glb.dll, ΠΊΠ°ΠΊ ΠΎΠΏΠΈΡΠ°Π½ΠΎ Π² ΡΠ°Π·Π΄Π΅Π»Π΅ Β«Π‘Π±ΠΎΡΠΊΠ°Β». ΠΠΎΡΠΎΠ²ΡΡ ΡΠ΅Π»ΠΈΠ·ΠΎΠ² ΠΏΠΎΠΊΠ° Π½Π΅Ρ. -
ΠΠΎΠ»ΠΎΠΆΠΈΡΠ΅ DLL ΡΡΠ΄ΠΎΠΌ Ρ ΠΌΠΎΠ΄ΠΎΠΌ ΠΈ ΡΠ²ΡΠΆΠΈΡΠ΅ Π½ΡΠΆΠ½ΡΠ΅ ΡΡΠ½ΠΊΡΠΈΠΈ:
Linker linker = Linker.nativeLinker(); SymbolLookup lib = SymbolLookup.libraryLookup(dllPath, Arena.global()); MethodHandle open = linker.downcallHandle(lib.find("grn2glb_open").orElseThrow(), FunctionDescriptor.of(ADDRESS, ADDRESS, JAVA_LONG)); MethodHandle export = linker.downcallHandle(lib.find("grn2glb_export_glb").orElseThrow(), FunctionDescriptor.of(JAVA_INT, ADDRESS, ADDRESS, ADDRESS)); // grn2glb_texture_count, grn2glb_texture_file_name, grn2glb_set_texture_rgba, // grn2glb_free, grn2glb_close ΠΈ grn2glb_last_error ΡΠ²ΡΠ·ΡΠ²Π°ΡΡΡΡ ΡΠ°ΠΊ ΠΆΠ΅.
-
ΠΡΠΊΡΠΎΠΉΡΠ΅ ΠΌΠΎΠ΄Π΅Π»Ρ, Π΄Π°ΠΉΡΠ΅ ΠΏΠΈΠΊΡΠ΅Π»ΠΈ Π²Π½Π΅ΡΠ½ΠΈΠΌ ΡΠ΅ΠΊΡΡΡΡΠ°ΠΌ ΠΈ Π·Π°Π±Π΅ΡΠΈΡΠ΅ GLB:
try (Arena arena = Arena.ofConfined()) { MemorySegment grn = arena.allocateFrom(JAVA_BYTE, grnBytes); MemorySegment model = (MemorySegment) open.invokeExact(grn, (long) grnBytes.length); // ΠΠ»Ρ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΡΠ»ΠΎΡΠ°, Π³Π΄Π΅ grn2glb_texture_has_pixels Π²Π΅ΡΠ½ΡΠ»Π° 0: // grn2glb_texture_file_name Π½Π°Π·ΠΎΠ²ΡΡ ΡΠ°ΠΉΠ», grn2glb_set_texture_rgba ΠΏΡΠΈΠΌΠ΅Ρ ΠΏΠΈΠΊΡΠ΅Π»ΠΈ. MemorySegment outData = arena.allocate(ADDRESS); MemorySegment outSize = arena.allocate(JAVA_LONG); int rc = (int) export.invokeExact(model, outData, outSize); MemorySegment glb = outData.get(ADDRESS, 0).reinterpret(outSize.get(JAVA_LONG, 0)); byte[] glbBytes = glb.toArray(JAVA_BYTE); free.invokeExact(outData.get(ADDRESS, 0)); close.invokeExact(model); }
ΠΡΠ»ΠΈ open Π²Π΅ΡΠ½ΡΠ»Π° NULL ΠΈΠ»ΠΈ ΠΊΠΎΠ΄ ΠΌΠ΅Π½ΡΡΠ΅ Π½ΡΠ»Ρ, grn2glb_last_error()
ΠΎΠ±ΡΡΡΠ½ΠΈΡ ΠΏΡΠΈΡΠΈΠ½Ρ. ΠΠΎΠ»Π½ΡΠΉ ΠΊΠΎΠ½ΡΡΠ°ΠΊΡ ΠΎΠΏΠΈΡΠ°Π½ Π²
include/grn2glb.h.
| Π€ΡΠ½ΠΊΡΠΈΡ | Π§ΡΠΎ Π΄Π΅Π»Π°Π΅Ρ |
|---|---|
grn2glb_api_version() |
ΠΠ΅ΡΡΠΈΡ ABI. Π‘ΡΠ°Π²Π½ΠΈΡΠ΅ Π΅Ρ Ρ GRN2GLB_API_VERSION Π΄ΠΎ Π΄ΡΡΠ³ΠΈΡ
Π²ΡΠ·ΠΎΠ²ΠΎΠ² |
grn2glb_open(data, size) |
Π Π°Π·Π±ΠΈΡΠ°Π΅Ρ ΠΌΠΎΠ΄Π΅Π»Ρ ΠΈΠ· Π±Π°ΠΉΡΠΎΠ² ΠΈ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅Ρ Π΅Ρ Π΄Π΅ΡΠΊΡΠΈΠΏΡΠΎΡ |
grn2glb_texture_count(model) |
Π§ΠΈΡΠ»ΠΎ ΡΠ»ΠΎΡΠΎΠ² ΡΠ΅ΠΊΡΡΡΡ |
grn2glb_texture_name(model, slot) |
ΠΠΌΡ ΡΠ»ΠΎΡΠ°, ΠΊΠ°ΠΊ ΠΎΠ½ΠΎ Π·Π°ΠΏΠΈΡΠ°Π½ΠΎ Π² GRN |
grn2glb_texture_file_name(model, slot) |
ΠΠΌΡ ΡΠ°ΠΉΠ»Π° ΡΠ΅ΠΊΡΡΡΡΡ, ΠΊΠ°ΠΊ ΠΎΠ½ΠΎ Π·Π°ΠΏΠΈΡΠ°Π½ΠΎ Π² GRN |
grn2glb_texture_format(model, slot) |
ΠΠΎΠ΄ ΡΠΎΡΠΌΠ°ΡΠ°: 7 β Π²Π½Π΅ΡΠ½ΠΈΠΉ ΡΠ°ΠΉΠ», 4 ΠΈ 5 β VTex, 0, 1 ΠΈ 6 β ΡΡΡΡΠ΅ ΠΏΠΈΠΊΡΠ΅Π»ΠΈ |
grn2glb_texture_size(model, slot, &w, &h) |
Π Π°Π·ΠΌΠ΅Ρ ΡΠ΅ΠΊΡΡΡΡΡ Π² ΠΏΠΈΠΊΡΠ΅Π»ΡΡ |
grn2glb_texture_has_pixels(model, slot) |
1, Π΅ΡΠ»ΠΈ ΠΏΠΈΠΊΡΠ΅Π»ΠΈ ΡΠΆΠ΅ Π΅ΡΡΡ, ΠΈ 0, Π΅ΡΠ»ΠΈ ΠΈΡ
ΠΆΠ΄ΡΡ ΠΎΡ Π²Π°Ρ |
grn2glb_set_texture_rgba(model, slot, rgba, w, h) |
ΠΡΠΈΠ½ΠΈΠΌΠ°Π΅Ρ ΠΏΠΈΠΊΡΠ΅Π»ΠΈ RGBA Π΄Π»Ρ ΡΠ»ΠΎΡΠ° |
grn2glb_export_glb(model, &data, &size) |
Π‘ΠΎΠ±ΠΈΡΠ°Π΅Ρ GLB Π² Π±ΡΡΠ΅Ρ |
grn2glb_free(buffer) |
ΠΡΠ²ΠΎΠ±ΠΎΠΆΠ΄Π°Π΅Ρ Π±ΡΡΠ΅Ρ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠΈ |
grn2glb_close(model) |
ΠΠ°ΠΊΡΡΠ²Π°Π΅Ρ ΠΌΠΎΠ΄Π΅Π»Ρ |
grn2glb_last_error() |
Π’Π΅ΠΊΡΡ ΠΏΠΎΡΠ»Π΅Π΄Π½Π΅ΠΉ ΠΎΡΠΈΠ±ΠΊΠΈ Π² ΡΠ΅ΠΊΡΡΠ΅ΠΌ ΠΏΠΎΡΠΎΠΊΠ΅ |
ΠΠΌΠ΅Π½Π° ΠΏΡΠΈΡ ΠΎΠ΄ΡΡ Π±Π°ΠΉΡ Π² Π±Π°ΠΉΡ, ΠΊΠ°ΠΊ ΠΈΡ Ρ ΡΠ°Π½ΠΈΡ GRN. Π Sacred ΡΡΠΎ ASCII, ΠΎΡΡΠ°Π»ΡΠ½ΠΎΠ΅ ΡΠΈΡΠ°ΠΉΡΠ΅ ΠΊΠ°ΠΊ windows-1252. Π‘Π»ΠΎΡ Π±Π΅Π· ΠΏΠΈΠΊΡΠ΅Π»Π΅ΠΉ ΠΏΠΎΠΏΠ°Π΄Π°Π΅Ρ Π² GLB ΡΠ΅ΡΡΠΌ ΠΊΠ²Π°Π΄ΡΠ°ΡΠΎΠΌ 2Γ2.
Π’Π΅ΡΡ test_game ΠΏΡΠΎΡ
ΠΎΠ΄ΠΈΡ ΠΏΠΎ Π²ΡΠ΅ΠΌ 1571 ΠΌΠΎΠ΄Π΅Π»ΡΠΌ ΠΈΠ· PAK\models.pak ΠΈ
ΡΡΠΈΡΠ°Π΅Ρ ΡΠ»ΠΎΡΡ ΡΠ΅ΠΊΡΡΡΡ:
| Π€ΠΎΡΠΌΠ°Ρ | ΠΠΎΠ΄ | Π‘Π»ΠΎΡΠΎΠ² |
|---|---|---|
| ΠΠ½Π΅ΡΠ½ΠΈΠΉ ΡΠ°ΠΉΠ» | 7 | 1922 |
| VTex Π±Π΅Π· Π°Π»ΡΡΡ | 4 | 104 |
| VTex Ρ Π°Π»ΡΡΠΎΠΉ | 5 | 41 |
| Π‘ΡΡΠΎΠΉ RGBA | 1 | 9 |
| Π‘ΡΡΠΎΠΉ RGBX | 0 | 6 |
Π‘ΠΊΠ΅Π»Π΅Ρ Ρ Π²Π΅ΡΠ°ΠΌΠΈ Π΅ΡΡΡ Ρ 1009 ΠΌΠΎΠ΄Π΅Π»Π΅ΠΉ. Π‘ΠΆΠ°ΡΠΈΡ DXT Π½ΠΈ ΠΎΠ΄Π½Π° ΠΌΠΎΠ΄Π΅Π»Ρ Π½Π΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅Ρ, ΠΏΠΎΡΡΠΎΠΌΡ Π΅Π³ΠΎ Π΄Π΅ΠΊΠΎΠ΄Π΅Ρ Ρ ΡΠ±ΡΠ°Π».
- ΠΠ½ΠΈΠΌΠ°ΡΠΈΠΈ ΠΏΠ°ΡΡΠ΅Ρ ΡΠΈΡΠ°Π΅Ρ, Π½ΠΎ ΠΏΡΠΈΠ²ΡΠ·Π°ΡΡ ΠΊ ΠΌΠΎΠ΄Π΅Π»ΠΈ Π΄Π²ΠΈΠΆΠ΅Π½ΠΈΠ΅ ΠΈΠ· ΠΎΡΠ΄Π΅Π»ΡΠ½ΠΎΠ³ΠΎ GRN ΠΏΠΎΠΊΠ° Π½Π΅Π»ΡΠ·Ρ. ΠΠ· 1571 ΠΌΠΎΠ΄Π΅Π»ΠΈ Π°Π½ΠΈΠΌΠ°ΡΠΈΡ Π² GLB ΠΏΠΎΠ»ΡΡΠ°Π΅Ρ ΡΠΎΠ»ΡΠΊΠΎ ΠΎΠ΄Π½Π°.
- Π‘ΠΊΠΈΠ½, ΡΡΡΡΠ°Π²Ρ ΠΈ Π²Π΅ΡΠ° ΠΏΠΎΠΏΠ°Π΄Π°ΡΡ Π² GLB, ΠΈ Π²Π°Π»ΠΈΠ΄Π°ΡΠΎΡ Khronos ΠΈΡ ΠΏΡΠΈΠ½ΠΈΠΌΠ°Π΅Ρ. ΠΠ°ΠΊ ΠΌΠ΅Ρ Π΄Π΅ΡΠΎΡΠΌΠΈΡΡΠ΅ΡΡΡ Π² ΠΏΠΎΠ·Π΅, Π΅ΡΡ Π½ΠΈΠΊΡΠΎ Π½Π΅ ΠΏΡΠΎΠ²Π΅ΡΡΠ».
- ΠΠ±ΡΠ°ΡΠ½ΠΎΠ³ΠΎ Π½Π°ΠΏΡΠ°Π²Π»Π΅Π½ΠΈΡ, ΠΈΠ· GLB Π² GRN, Π·Π΄Π΅ΡΡ Π½Π΅Ρ.
ΠΡΠΆΠ½Ρ MSVC x64 ΠΈ CMake 3.22 ΠΈΠ»ΠΈ Π½ΠΎΠ²Π΅Π΅. ΠΠ· Developer Command Prompt:
cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release
cmake --build build
ctest --test-dir build --output-on-failure
DLL ΠΏΠΎΡΠ²ΠΈΡΡΡ Π² build\bin\grn2glb.dll. Π’Π΅ΡΡΡ test_core ΠΈ test_abi ΠΈΠ³ΡΡ
Π½Π΅ ΡΡΠ΅Π±ΡΡΡ. test_game Π±Π΅ΡΡΡ ΠΌΠΎΠ΄Π΅Π»ΠΈ ΠΈΠ· ΠΈΠ³ΡΡ ΠΏΠΎ ΠΏΡΡΠΈ Π² GRN2GLB_GAME, Π° Π±Π΅Π·
ΠΈΠ³ΡΡ ΡΠΎΠΎΠ±ΡΠ°Π΅Ρ ΠΎ ΠΏΡΠΎΠΏΡΡΠΊΠ΅.
ΠΠ½ΠΎΠΏΠΊΠΈ Release Ρ ΡΠ΅ΠΏΠΎΠ·ΠΈΡΠΎΡΠΈΡ ΠΏΠΎΠΊΠ° Π½Π΅Ρ. CI ΡΠΎΠ±ΠΈΡΠ°Π΅Ρ ΠΈ ΡΠ΅ΡΡΠΈΡΡΠ΅Ρ ΠΊΠΎΠ΄ ΠΏΡΠΈ
ΠΊΠ°ΠΆΠ΄ΠΎΠΌ push Π² master ΠΈ Π΄Π»Ρ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ pull request ΠΈ Π½ΠΈΡΠ΅Π³ΠΎ Π½Π΅ ΠΏΡΠ±Π»ΠΈΠΊΡΠ΅Ρ.
ΠΠ±ΡΠΈΠ΅ ΠΏΡΠ°Π²ΠΈΠ»Π° ΠΎΠΏΠΈΡΠ°Π½Ρ Π² ΠΊΠΎΡΠ½Π΅Π²ΠΎΠΌ
CONTRIBUTING.
Π‘ΠΏΠ°ΡΠΈΠ±ΠΎ karolak6612 Π·Π° Π²ΡΠ΅ΠΌΡ, ΠΊΠΎΡΠΎΡΠΎΠ΅ ΡΡΠ»ΠΎ Π½Π° Π³Π»ΡΠ±ΠΎΠΊΠΎΠ΅ ΠΈΠ·ΡΡΠ΅Π½ΠΈΠ΅ ΡΠΎΡΠΌΠ°ΡΠ° Granny GRN Π²ΠΌΠ΅ΡΡΠ΅ Ρ ΠΠ-Π°Π³Π΅Π½ΡΠΎΠΌ. ΠΡΠ° Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ° β ΡΡΠ΅Π·Π°Π½Π½ΡΠΉ ΡΠΎΡΠΊ open-grn-converter, ΠΈ Π΅Π³ΠΎ ΠΈΡΡΠΎΡΠΈΡ ΠΊΠΎΠΌΠΌΠΈΡΠΎΠ² ΡΠΎΡ ΡΠ°Π½Π΅Π½Π° Π·Π΄Π΅ΡΡ.
ΠΡΡ
ΠΎΠ΄Π½ΡΠΉ ΠΊΠΎΠ΄ ΡΠ°ΡΠΏΡΠΎΡΡΡΠ°Π½ΡΠ΅ΡΡΡ ΠΏΠΎΠ΄ MIT, ΡΠΌ. LICENSE. ΠΡΠ°Π²Π°
ΠΏΡΠΈΠ½Π°Π΄Π»Π΅ΠΆΠ°Ρ karolak6612 ΠΈ ΠΌΠ½Π΅. ΠΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ β Π΄Π΅ΠΊΠΎΠ΄Π΅Ρ VTex Π²
src/codecs/vtex_*. ΠΠ½ ΠΎΡΠ½ΠΎΠ²Π°Π½ Π½Π° Π΄Π΅ΠΊΠΎΠ΄Π΅ΡΠ΅ Bink ΠΈΠ· FFmpeg
(libavcodec/bink.c ΠΈ binkdata.h) ΠΈ ΡΠ°ΡΠΏΡΠΎΡΡΡΠ°Π½ΡΠ΅ΡΡΡ ΠΏΠΎΠ΄
LGPL-2.1-or-later. ΠΠΎΠ»Π½ΡΠΉ ΡΠ΅ΠΊΡΡ Π»ΠΈΡΠ΅Π½Π·ΠΈΠΈ Π»Π΅ΠΆΠΈΡ Π²
LICENSES/LGPL-2.1.txt.
Π‘ΠΎΠ±ΡΠ°Π½Π½Π°Ρ grn2glb.dll ΡΠΎΠ΄Π΅ΡΠΆΠΈΡ ΡΡΠΎΡ ΠΊΠΎΠ΄, ΠΏΠΎΡΡΠΎΠΌΡ ΡΠ΅Π»ΠΈΠΊΠΎΠΌ ΡΠ°ΡΠΏΡΠΎΡΡΡΠ°Π½ΡΠ΅ΡΡΡ
ΠΏΠΎΠ΄ LGPL-2.1-or-later. ΠΠΎΠ΄ Π·Π°Π³ΡΡΠΆΠ°Π΅Ρ DLL Π΄ΠΈΠ½Π°ΠΌΠΈΡΠ΅ΡΠΊΠΈ ΡΠ΅ΡΠ΅Π· FFM (Panama), ΠΈ
LGPL ΡΡΠΎ ΡΠ°Π·ΡΠ΅ΡΠ°Π΅Ρ: ΡΠ°ΠΌ ΠΌΠΎΠ΄ ΠΌΠΎΠΆΠ΅Ρ ΠΈΠΌΠ΅ΡΡ Π»ΡΠ±ΡΡ Π»ΠΈΡΠ΅Π½Π·ΠΈΡ.
nlohmann/json ΠΈ
stb_image_write ΠΈΠ΄ΡΡ ΠΏΠΎΠ΄ ΡΠ²ΠΎΠΈΠΌΠΈ Π»ΠΈΡΠ΅Π½Π·ΠΈΡΠΌΠΈ.