mirror of
https://github.com/drewcassidy/quicktex.git
synced 2024-09-13 06:37:34 +00:00
rename some values for less confusion
From now on, "size" should refer to a value in bytes, whereas dimensions are in pixels or blocks and usually a 2-tuple
This commit is contained in:
parent
18e3089eb0
commit
2244b2117d
@ -5,60 +5,60 @@ import typing
|
|||||||
import math
|
import math
|
||||||
|
|
||||||
|
|
||||||
def pad(image: Image.Image, block_size=(4, 4)) -> Image.Image:
|
def pad(source: Image.Image, block_dimensions=(4, 4)) -> Image.Image:
|
||||||
"""
|
"""
|
||||||
Pad an image to be divisible by a specific block size. The input image is repeated into the unused areas so that bilinar filtering works correctly.
|
Pad an image to be divisible by a specific block size. The input image is repeated into the unused areas so that bilinar filtering works correctly.
|
||||||
|
|
||||||
:param image: Input image to add padding to. This will not be modified.
|
:param source: Input image to add padding to. This will not be modified.
|
||||||
:param block_size: The size of a single block that the output must be divisible by.
|
:param block_dimensions: The size of a single block that the output must be divisible by.
|
||||||
:return: A new image with the specified padding added.
|
:return: A new image with the specified padding added.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
assert all([dim > 0 for dim in block_size]), "Invalid block size"
|
assert all([dim > 0 for dim in block_dimensions]), "Invalid block size"
|
||||||
|
|
||||||
padded_size = tuple([
|
padded_dimensions = tuple([
|
||||||
math.ceil(i_dim / b_dim) * b_dim
|
math.ceil(i_dim / b_dim) * b_dim
|
||||||
for i_dim in image.size
|
for i_dim in source.size
|
||||||
for b_dim in block_size
|
for b_dim in block_dimensions
|
||||||
])
|
])
|
||||||
|
|
||||||
if padded_size == image.size:
|
if padded_dimensions == source.size:
|
||||||
# no padding is necessary
|
# no padding is necessary
|
||||||
return image
|
return source
|
||||||
|
|
||||||
output = Image.new(image.mode, padded_size)
|
output = Image.new(source.mode, padded_dimensions)
|
||||||
for x in range(math.ceil(padded_size[0] / image.width)):
|
for x in range(math.ceil(padded_dimensions[0] / source.width)):
|
||||||
for y in range(math.ceil(padded_size[1] / image.height)):
|
for y in range(math.ceil(padded_dimensions[1] / source.height)):
|
||||||
output.paste(image, (x * image.width, y * image.height))
|
output.paste(source, (x * source.width, y * source.height))
|
||||||
|
|
||||||
return output
|
return output
|
||||||
|
|
||||||
|
|
||||||
def mip_sizes(size: typing.Tuple[int, int], mip_count: typing.Optional[int] = None) -> typing.List[typing.Tuple[int, int]]:
|
def mip_sizes(dimensions: typing.Tuple[int, int], mip_count: typing.Optional[int] = None) -> typing.List[typing.Tuple[int, int]]:
|
||||||
"""
|
"""
|
||||||
Create a chain of mipmap sizes for a given source image size, where each image is half the size of the one before.
|
Create a chain of mipmap sizes for a given source source size, where each source is half the size of the one before.
|
||||||
Note that the division by 2 rounds down. So a 63x63 texture has as its next lowest mipmap level 31x31. And so on.
|
Note that the division by 2 rounds down. So a 63x63 texture has as its next lowest mipmap level 31x31. And so on.
|
||||||
|
|
||||||
See the `OpenGL wiki page on mipmaps <https://www.khronos.org/opengl/wiki/Texture#Mip_maps>`_ for more info.
|
See the `OpenGL wiki page on mipmaps <https://www.khronos.org/opengl/wiki/Texture#Mip_maps>`_ for more info.
|
||||||
|
|
||||||
:param size: Size of the source image
|
:param dimensions: Size of the source source in pixels
|
||||||
:param mip_count: Number of mipmap sizes to generate. By default, generate until the last mip level is 1x1.
|
:param mip_count: Number of mipmap sizes to generate. By default, generate until the last mip level is 1x1.
|
||||||
Resulting mip chain will be smaller if a 1x1 mip level is reached before this value.
|
Resulting mip chain will be smaller if a 1x1 mip level is reached before this value.
|
||||||
:return: A list of 2-tuples representing the size of each mip level, including ``size`` at element 0.
|
:return: A list of 2-tuples representing the dimensions of each mip level, including ``dimensions`` at element 0.
|
||||||
"""
|
"""
|
||||||
assert all([dim > 0 for dim in size]), "Invalid image size"
|
assert all([dim > 0 for dim in dimensions]), "Invalid source size"
|
||||||
if not mip_count:
|
if not mip_count:
|
||||||
mip_count = math.ceil(math.log2(max(size))) # maximum possible number of mips for a given image
|
mip_count = math.ceil(math.log2(max(dimensions))) # maximum possible number of mips for a given source
|
||||||
|
|
||||||
assert mip_count > 0, "mip_count must be greater than 0"
|
assert mip_count > 0, "mip_count must be greater than 0"
|
||||||
|
|
||||||
chain = []
|
chain = []
|
||||||
|
|
||||||
for mip in range(mip_count):
|
for mip in range(mip_count):
|
||||||
chain.append(size)
|
chain.append(dimensions)
|
||||||
size = tuple([max(dim // 2, 1) for dim in size])
|
dimensions = tuple([max(dim // 2, 1) for dim in dimensions])
|
||||||
|
|
||||||
if all([dim == 1 for dim in size]):
|
if all([dim == 1 for dim in dimensions]):
|
||||||
break # we've reached a 1x1 mip and can get no smaller
|
break # we've reached a 1x1 mip and can get no smaller
|
||||||
|
|
||||||
return chain
|
return chain
|
||||||
|
Loading…
Reference in New Issue
Block a user