Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

vtf :jpg_to_vtf .I need some example #16

Open
Agnes4m opened this issue Jan 29, 2023 · 12 comments
Open

vtf :jpg_to_vtf .I need some example #16

Agnes4m opened this issue Jan 29, 2023 · 12 comments
Labels

Comments

@Agnes4m
Copy link

Agnes4m commented Jan 29, 2023

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
Copy link
Owner

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
Copy link
Author

Agnes4m commented Jan 29, 2023

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
Copy link
Author

Agnes4m commented Jan 29, 2023

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.

  • In my own understanding, largest_ The frame is assigned from vtf. get(), but in the end it is directly used. Are there any key steps missing? Do I need to load this frame file into vtf by any method?
  • I compared the size produced by other software, and found that the size would not exceed [510.0625kb] under the size of 1024 * 1024, but the size of the file I converted was [683kb], far exceeding this value. Maybe the file cannot be loaded if it exceeds this size.
  • I use python 3.9.10. I hope it is not this error

image

@TeamSpen210
Copy link
Owner

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
Copy link
Author

Agnes4m commented Jan 30, 2023

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
Copy link
Author

Agnes4m commented Jan 31, 2023

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

@Agnes4m Agnes4m closed this as completed Jan 31, 2023
@Agnes4m
Copy link
Author

Agnes4m commented Feb 1, 2023

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())

@Agnes4m Agnes4m reopened this Feb 1, 2023
@joethegamer100
Copy link

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
Copy link
Owner

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
Copy link
Author

Agnes4m commented Feb 3, 2023

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
Copy link
Owner

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

@Agnes4m
Copy link
Author

Agnes4m commented Feb 4, 2023

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants