TeamSpen210 / srctools

Modules for working with Valve's Source Engine file formats.
Other
59 stars 16 forks source link

vtf :jpg_to_vtf .I need some example #16

Open Agnes4m opened 1 year ago

Agnes4m commented 1 year ago

I want to convert a jpg image into a vtf file, but I don't know where the problem is. The file is wrong

from srctools.vtf import VTF
import io
a = VTF(width=1024,height=1024)
with open('C:\\Users\\73580\\Desktop\\R.jpg','rb') as fi:
    img1 = fi.read()
img1 = io.BytesIO(img1)
a.save(file=img1)
with open('C:\\Users\\73580\\Desktop\\file.vtf','wb') as f:
    a.save(f)
TeamSpen210 commented 1 year ago

You'll need pillow to do the parsing of the JPG image, the srctools module only handles the VTF format itself:

from PIL import Image
from srctools.vtf import VTF, ImageFormats

# Specify the format here to convert to when saving.
vtf = VTF(1024, 1024, fmt=ImageFormats.DXT1)
img = Image.open('C:\\Users\\73580\\Desktop\\R.jpg')
largest_frame = vtf.get()  # This retrieves the first frame with the largest mipmap size.
# Copy into the frame, the format here is what PIL uses for non-transparent images. You'd want ImageFormats.RGBA8888 for transparent ones.
largest_frame.copy_from(img.tobytes(), ImageFormats.RGB888)
with open('C:\\Users\\73580\\Desktop\\file.vtf', 'wb') as f:
    vtf.save(f)
Agnes4m commented 1 year ago

I'm sorry I still have some problems.

from PIL import Image
from srctools.vtf import VTF, ImageFormats

vtf = VTF(1024, 1024, fmt=ImageFormats.DXT1)
img = Image.open('C:\\Users\\73580\\Desktop\\R.png')
img = img.resize((1024, 1024))
largest_frame = vtf.get()
largest_frame.copy_from(img.tobytes(), ImageFormats.RGB888)
with open('C:\\Users\\73580\\Desktop\\file.vtf', 'wb') as f:
    vtf.save(f)
Traceback (most recent call last):
  File "c:\Users\73580\Desktop\templates\test.py", line 8, in <module>
    largest_frame.copy_from(img.tobytes(), ImageFormats.RGB888)
  File "D:\python3.9.10\lib\site-packages\srctools\vtf.py", line 396, in copy_from
    raise ValueError(
ValueError: Expected 3145728 bytes for 1024x1024 ImageFormats.RGB888 image, got 4194304 bytes!

What is the problem with the size of the picture?

Agnes4m commented 1 year ago

I realized my mistake because the image needs RGBA8888, and the size of direct zoom is blank.

However, I found that after such modification, the generated vtf file could not load images in L4D2 painting.My own guess may be the following reasons.

image

TeamSpen210 commented 1 year ago

You don't need to assign the frame no, get() just retrieves a reference from inside the VTF object. You might need to change the VTF version also? Try passing version=(7, 2) to the VTF constructor. The size probably isn't an issue, depending on the image format it can vary quite a lot.

Agnes4m commented 1 year ago

I tried the following methods, but failed to get the vtf image that can be opened correctly.Above is (7,5), below is (7,2)

vtf = VTF(512, 512, fmt = ImageFormats.DXT1)
vtf = VTF(512, 512, fmt = ImageFormats.DXT1,version=(7,2))
vtf = VTF(512, 512, fmt = ImageFormats.RGBA8888)
vtf = VTF(512, 512, fmt = ImageFormats.RGBA8888,,version=(7,2))
...
img = img.resize((512,512))

image image

I'm not sure if this is the problem.

I noticed in the document: fmt:

ImageFormats=ImageFormats.RGBA8888,
thumb_ fmt: ImageFormats = ImageFormats.DXT1,

image

By the way, because at the beginning, I tried to generate vtf images in various ways, and then loaded some of these vtf images into L4D2. The good news is that one of them is successful. The bad news is that I don't remember how to write the parameters.

I only know that the first line changes,that isvtf = VTF(512, 512, fmt = ImageFormats.DXT1) image

Agnes4m commented 1 year ago

I got it,this is true. vtf = VTF(512, 512, fmt = ImageFormats.DXT5,thumb_fmt = ImageFormats.DXT1,version=(7,2))

Agnes4m commented 1 year ago

I encountered a new problem when I tried to implement it on UBUNTU20.04

In the paint selection interface of the game, I see that the picture is loaded correctly, but the picture is invalid during the game,press T without any pictures image

I don't know whether it is my own code. I hope you can help me

from PIL import Image
from srctools.vtf import VTF, ImageFormats
from io import BytesIO

async def img_to_vtf(pic_byte:bytes,tag) -> BytesIO:
    pic = BytesIO()
    pic.write(pic_byte)
    pic.seek(0)
    pic = Image.open(pic).convert('RGBA')
    vtf_io = BytesIO()
    vtf_ = VTF(1024, 1024, fmt = ImageFormats.DXT5,thumb_fmt = ImageFormats.DXT1,version=(7,2))
    pic = pic.resize((1024,1024))
    largest_frame = vtf_.get() 
    largest_frame.copy_from(pic.tobytes(), ImageFormats.RGBA8888)
    vtf_.save(vtf_io)
    return vtf_io

async def upload_file( file: BytesIO, filename: str,):
    ““”Get temporary files“””
    with tempfile.NamedTemporaryFile("wb+") as f:
        f.write(file.getbuffer())
joethegamer100 commented 1 year ago

personally to convert images into vtfs I use this: https://rafradek.github.io/Mishcatt/ its a tf2 spray converter but its worked well for me

TeamSpen210 commented 1 year ago

Perhaps I messed up something in the C extension. Try adding the following to your script before the from srctools import ... line to disable the C accelerator:

import sys
sys.modules["srctools._cy_vtf_readwrite"] = None
Agnes4m commented 1 year ago

I think these may be necessary because when I try to write

import sys
sys.modules["srctools._cy_vtf_readwrite"] = None

The error type is NotImplementedError

  File "/home/ubuntu/bot/game/nb2/./src/plugins/nonebot_plugin_l4d2_server/l4d2_image/vtfs.py", line 42, in img_to_vtf
    vtf_.save(file = vtf_io)
  File "/usr/local/lib/python3.10/site-packages/srctools/vtf.py", line 877, in save
    _format_funcs.save(self.low_format, self._low_res._data, data, self._low_res.width, self._low_res.height)
  File "/usr/local/lib/python3.10/site-packages/srctools/_py_vtf_readwrite.py", line 130, in save
    raise NotImplementedError(f"Saving {fmt.name} not implemented!") from None
NotImplementedError: Saving DXT5 not implemented!
TeamSpen210 commented 1 year ago

Oh right, you'll need to change the fmt= and thumb_fmt= to ImageFormspats.RGBA8888.

Agnes4m commented 1 year ago

When vtf_ = VTF(1024, 1024, fmt = ImageFormats.RGBA8888,thumb_fmt = ImageFormats.RGBA8888,version=(7,2)),this picture is wrong image

If fmt= or thumb_fmt= is ImageFormspats. DXT5 or ImageFormspats. DXT1, an error will be reported NotImplementedError: Saving DXT5/DX1 not implemented!

I also tried change version=(7,2) to version=(7,5),it doesn't work