Skip to content

Commit 03410ce

Browse files
authored
Use buffer for ClassIcon EditableImages (#1149)
1 parent 825726c commit 03410ce

File tree

2 files changed

+56
-21
lines changed

2 files changed

+56
-21
lines changed

plugin/src/App/Components/ClassIcon.lua

Lines changed: 53 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
local StudioService = game:GetService("StudioService")
22
local AssetService = game:GetService("AssetService")
33

4+
type CachedImageInfo = {
5+
pixels: buffer,
6+
size: Vector2,
7+
}
8+
49
local Rojo = script:FindFirstAncestor("Rojo")
510
local Plugin = Rojo.Plugin
611
local Packages = Rojo.Packages
@@ -11,55 +16,84 @@ local e = Roact.createElement
1116

1217
local EditableImage = require(Plugin.App.Components.EditableImage)
1318

14-
local imageCache = {}
15-
local function getImageSizeAndPixels(image)
16-
if not imageCache[image] then
17-
local editableImage = AssetService:CreateEditableImageAsync(image)
19+
local imageCache: { [string]: CachedImageInfo } = {}
20+
21+
local function cloneBuffer(b: buffer): buffer
22+
local newBuffer = buffer.create(buffer.len(b))
23+
buffer.copy(newBuffer, 0, b)
24+
return newBuffer
25+
end
26+
27+
local function getImageSizeAndPixels(image: string): (Vector2, buffer)
28+
local cachedImage = imageCache[image]
29+
30+
if not cachedImage then
31+
local editableImage = AssetService:CreateEditableImageAsync(Content.fromUri(image))
32+
local size = editableImage.Size
33+
local pixels = editableImage:ReadPixelsBuffer(Vector2.zero, size)
1834
imageCache[image] = {
19-
Size = editableImage.Size,
20-
Pixels = editableImage:ReadPixels(Vector2.zero, editableImage.Size),
35+
pixels = pixels,
36+
size = size,
2137
}
38+
39+
return size, cloneBuffer(pixels)
2240
end
2341

24-
return imageCache[image].Size, table.clone(imageCache[image].Pixels)
42+
return cachedImage.size, cloneBuffer(cachedImage.pixels)
2543
end
2644

2745
local function getRecoloredClassIcon(className, color)
2846
local iconProps = StudioService:GetClassIcon(className)
2947

3048
if iconProps and color then
31-
local success, editableImageSize, editableImagePixels = pcall(function()
32-
local size, pixels = getImageSizeAndPixels(iconProps.Image)
49+
--stylua: ignore
50+
local success, editableImageSize, editableImagePixels = pcall(function(_iconProps: { [any]: any }, _color: Color3): (Vector2, buffer)
51+
local size, pixels = getImageSizeAndPixels(_iconProps.Image)
52+
local pixelsLen = buffer.len(pixels)
3353

3454
local minVal, maxVal = math.huge, -math.huge
35-
for i = 1, #pixels, 4 do
36-
if pixels[i + 3] == 0 then
55+
56+
for i = 0, pixelsLen, 4 do
57+
if buffer.readu8(pixels, i + 3) == 0 then
3758
continue
3859
end
39-
local pixelVal = math.max(pixels[i], pixels[i + 1], pixels[i + 2])
60+
local pixelVal = math.max(
61+
buffer.readu8(pixels, i),
62+
buffer.readu8(pixels, i + 1),
63+
buffer.readu8(pixels, i + 2)
64+
)
4065

4166
minVal = math.min(minVal, pixelVal)
4267
maxVal = math.max(maxVal, pixelVal)
4368
end
4469

45-
local hue, sat, val = color:ToHSV()
46-
for i = 1, #pixels, 4 do
47-
if pixels[i + 3] == 0 then
70+
local hue, sat, val = _color:ToHSV()
71+
72+
for i = 0, pixelsLen, 4 do
73+
if buffer.readu8(pixels, i + 3) == 0 then
4874
continue
4975
end
50-
51-
local pixelVal = math.max(pixels[i], pixels[i + 1], pixels[i + 2])
76+
local gIndex = i + 1
77+
local bIndex = i + 2
78+
79+
local pixelVal = math.max(
80+
buffer.readu8(pixels, i),
81+
buffer.readu8(pixels, gIndex),
82+
buffer.readu8(pixels, bIndex)
83+
)
5284
local newVal = val
5385
if minVal < maxVal then
5486
-- Remap minVal - maxVal to val*0.9 - val
5587
newVal = val * (0.9 + 0.1 * (pixelVal - minVal) / (maxVal - minVal))
5688
end
5789

5890
local newPixelColor = Color3.fromHSV(hue, sat, newVal)
59-
pixels[i], pixels[i + 1], pixels[i + 2] = newPixelColor.R, newPixelColor.G, newPixelColor.B
91+
buffer.writeu8(pixels, i, newPixelColor.R)
92+
buffer.writeu8(pixels, gIndex, newPixelColor.G)
93+
buffer.writeu8(pixels, bIndex, newPixelColor.B)
6094
end
6195
return size, pixels
62-
end)
96+
end, iconProps, color)
6397
if success then
6498
iconProps.EditableImagePixels = editableImagePixels
6599
iconProps.EditableImageSize = editableImageSize

plugin/src/App/Components/EditableImage.lua

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,16 @@ function EditableImage:init()
1212
end
1313

1414
function EditableImage:writePixels()
15-
local image = self.ref.current
15+
local image = self.ref.current :: EditableImage
16+
1617
if not image then
1718
return
1819
end
1920
if not self.props.pixels then
2021
return
2122
end
2223

23-
image:WritePixels(Vector2.zero, self.props.size, self.props.pixels)
24+
image:WritePixelsBuffer(Vector2.zero, self.props.size, self.props.pixels)
2425
end
2526

2627
function EditableImage:render()

0 commit comments

Comments
 (0)