scaling down matrix
while displaying images scaled up is not a big problem (the first quick and dirty solution already begins with the "interp" of jit pwindow), scaling down seems more difficult.
how would you display an image which is 400*400 in a 100*100 pwindow?
nearest neighbour/line skipping like present in pwindow, rota, resamp and others is out of question.
i´d be willing to put the image on a GL plane if you show me how i can get a square figure pixel-exact into a pwindow and apply an existing jitter matrix.
a solution using a pixel matrix would be preferred though. CPU or scheduler load is not an issue.
25% in photoshop - that quality would be sufficient.
![](https://cycling74-web-uploads.s3.amazonaws.com/574f1ffc3b4a14995d983d8f/2023-08-27T17:44:18Z/scltst.png)
![](https://cycling74-web-uploads.s3.amazonaws.com/574f1ffc3b4a14995d983d8f/2023-08-27T17:44:28Z/scltst2.png)
you can perform trilinear sampling using the GPU and a simple shader around the textureLod function. We actually ship with this shader.
![](https://cycling74-web-uploads.s3.amazonaws.com/532091d1782ba55b54131523/2023-08-28T15:59:41Z/Screenshot 2023-08-28 at 11.58.00 AM.png)
thanks rob, that works fine and will be my to go solution.
if anyone has an idea how to do it completely different, incl. more inefficiently (jit op? pixel matrix?) let me know.
for what it's worth here's chatgpt's pseudocode for this:
function trilinearSample(image, x, y, level):
if level == 0:
return image[x, y] // Return the pixel value at the current level
levelWidth = image.width / (2^level)
levelHeight = image.height / (2^level)
// Calculate coordinates in the current level
currentX = x / (2^level)
currentY = y / (2^level)
// Calculate coordinates in the neighboring levels
lowerLevelX = floor(currentX)
lowerLevelY = floor(currentY)
upperLevelX = ceil(currentX)
upperLevelY = ceil(currentY)
// Calculate fractional values for interpolation
fracX = currentX - lowerLevelX
fracY = currentY - lowerLevelY
// Sample pixels from neighboring mipmaps
lowerLevelSample00 = trilinearSample(image, lowerLevelX, lowerLevelY, level - 1)
lowerLevelSample10 = trilinearSample(image, upperLevelX, lowerLevelY, level - 1)
lowerLevelSample01 = trilinearSample(image, lowerLevelX, upperLevelY, level - 1)
lowerLevelSample11 = trilinearSample(image, upperLevelX, upperLevelY, level - 1)
// Perform trilinear interpolation in both dimensions
interpolatedX0 = lowerLevelSample00 * (1 - fracX) + lowerLevelSample10 * fracX
interpolatedX1 = lowerLevelSample01 * (1 - fracX) + lowerLevelSample11 * fracX
interpolatedValue = interpolatedX0 * (1 - fracY) + interpolatedX1 * fracY
return interpolatedValue
function downsampleImage(image, targetWidth, targetHeight):
resultImage = new Image(targetWidth, targetHeight)
for y = 0 to targetHeight - 1:
for x = 0 to targetWidth - 1:
// Calculate the level to sample from based on target size
level = log2(image.width / targetWidth)
resultImage[x, y] = trilinearSample(image, x, y, level)
return resultImage
if jit.fastblur had a radial mode and allowed 4 instead of only 3 pixels distance, it would be ok, too. (except for the image borders, but i know how to deal with this, as i had to do the same in PS.... not above, but for actual image size changes)
another CPU solution would be "jit.dimop @op avg @step 4 4".