It's Impossible to Get an Image ID From a Decal ID

As a Roblox developer, it is currently impossible to get a usable image ID from a website-facing decal ID. This causes a headache of manually searching around the ID range in order to find an ID that’s actually usable in-game. Additionally, this makes it near impossible to smoothly implement a feature that accepts user-submitted images (custom shop signs, etc).

An API to get an image ID from a decal ID would be ideal. More broadly, I don’t see why images and decals need to separate assets at all, and seeing those two converge would be awesome.

If Roblox is able to address this issue, it would improve my development experience because I wouldn’t need to perform as many awkward workarounds to use an image ID in my game.

136 Likes

Isn’t this what rbxthumb is for, or does that not load the image the same way you’d expect it to? Going off the fact that it’s a ContentId for loading thumbnails and the image is not the decal’s thumbnail.

11 Likes

Massively support.

In Lua Learning, users can add images to their tutorials. They input an ID, and then my code has to go through a massive headache to actually display it.

My code first determines if it’s a decal or an image. If an image, give the user a trophy and a cookie for doing it so neatly and then display the image. But if it’s a decal, oh boy.

I have to iterate through IDs, slowly subtracting 1 and checking if that asset is an image, made by the same creator as the decal. If it is, hope and pray that we found the image and display that. If not, do the next ID. This terrible method uses so much of the request budget that sometimes it causes it to fill up and start failing requests, which is obviously a big issue. If I make it queue them up more slowly then images will simply take too long to load and the user might never even see it.

If we can’t guess the image, then we resort to using the rbxthumb that @colbert2677 has brought up. The reason this is a last resort is because 420x420 is absolutely worthless if the user uploaded a 1024x1024 image with text or details that are important.


My situation is not unique. Many games allow users to input an ID for custom spray tags or avatar icons or something. Players (and even many devs) don’t even know that decals and images are different, and usually input decals and we are left struggling to convert to image.

Please allow us to get the Image ID from a Decal ID!

69 Likes

I think the better proposal would be making it so decals aren’t uploaded as decals but rather images. Because apparently there is a difference between decal Id and image Id.

I was writing my first plugin that i actually use for myself, spent almost days wondering why it was unable to load plugin icon. Turns out the id of the decal i uploaded was the decal id and not the image id.

12 Likes

This is definitely a big pain when trying to populate or change anything with decals scriptwise. Would love to see this functionality extended to faces as well, as they follow a very similar flow and issue.

3 Likes

In the meantime if you just need to do it off the website you can do this

8965b3ac7c37068b790063a76daa0f35

But I definitely support having API support for it

4 Likes

That’s with the use of a plugin (I believe BTRoblox?) I don’t believe you can directly reach the Image ID at all from the Decal page right now.

7 Likes

Ah, you’re right. BTRoblox has so many nifty well integrated features that I forget they’re not vanilla - most of them should be. I’ve also had it for so long so I hardly remember what the roblox site was like before it lol

8 Likes

The fact that we need third party tools highlights how important this feature request really is. Images and Decals are an ambiguous mess at the moment.

17 Likes

Does inserting the decal and reading its ID not work? This is what we do internally for the Properties widget when an assetId is pasted in. For Lua it would look something like

local InsertService = game:GetService("InsertService")
local MarketplaceService = game:GetService("MarketplaceService")

function getImageIdFromDecal(decalId)
	local assetInfo = MarketplaceService:GetProductInfo(decalId, Enum.InfoType.Asset)
	
	assert(assetInfo.IsPublicDomain)
	assert(assetInfo.AssetTypeId == Enum.AssetType.Decal.Value)
	
	local decal = InsertService:LoadAsset(decalId):FindFirstChildWhichIsA("Decal")
	return decal.Texture
end

print(getImageIdFromDecal(3339338289))

This is also likely what the requested API would do behind the scenes.

55 Likes

I’m surprised decals are even a thing still, it feels really strange that we have a web asset that doesn’t actually do anything (since decal instances need an image id, not a decal id).

I’d be much happier if Decals were hidden from the website, and stopped being created when an image is uploaded - it’s much easier to view the actual image assets now with the create.roblox.com/creations page.


Linking this thread from a couple of years ago: Stop creating decal assets

16 Likes

An exposed method which handles this for us would be much more generous than us having to use (and some day, people will find) this example (which honestly I did not know you could do this).

The API would be a quality of life change that would be well received with opened arms.

2 Likes

I never knew this existed. I’ll be updating my codebase with this method for now, but a proper API would still be preferable.

Also, I’m not sure how no one knew about this method. Is there any documentation for it?

4 Likes

Both are pretty thoroughly documented.

3 Likes

This seems really esoteric and is not common knowledge nor easy for people to figure out; if you browse the forum you can see that the general approach people take towards doing this is to use crazy hacks or simply do something else. This is too close to being a hidden trick that I don’t think doing this in this manner should be considered canonical.

11 Likes

If we add something akin to MarketplaceService:GetAssetFromDecal() or AssetService:GetAssetFromDecal(), how would it be any more discoverable than those two methods? If developers cannot find either of the existing ones, is this new API different?

9 Likes

This workaround relies on knowing that creating a decal results in the texture field being set to the image id. This behavior is only directly observed in Studio through the properties widget when you try to set the texture property and it’s easy to assume that it is Studio doing that conversion, not the instance itself.

Developers will go to Google or to the DevHub first and will typically try searching directly, or else browsing API pages for related services. In many cases they may just try intellisense directly in Studio and hope they get lucky. It is massively easier to discover an API function that directly does this than it is to connect the dots and come up with some workaround that jumps through InsertService. The existence of this function in intellisense under a logical service would improve discovery without leaving Studio, and the existence of the DevHub API page for a function like this with sufficient keywords on the page would solve this through search engine indexing.

12 Likes

There’s a big difference between a method designed and advertised to do a specific task and a sequence of methods that happen to make the functionality possible via a still overly complex workaround. Kind of like how we have helpful coordinate math functions like CFrame.lookAt despite us technically being able to achieve the same functionality through other more complex means.

11 Likes

LoadAsset doesn’t allow us to import assets that are not owned by Roblox or the Game owner.

For players to use decals their own, how exactly can this suffice that use case?

An asset loaded by this function must be created or owned by either the game creator or Roblox. Additionally, benign asset types such as t-shirts, shirts, pants and avatar accessories are loadable from any game as they are public.

I know this method exist but never cared for it because of this flaw

19 Likes

Clearly there’s metadata somewhere in a decal asset that links it to the image ID. I agree that this would be great to have without needing to go through both MarketplaceService and InsertService.

8 Likes