GET ImageId from DecalId In-Game [DEPRECIATED DO NOT USE]

[UPDATE] : Fixed failure to parse XML returned by Roblox as a result of me not allowing data to load properly. All successful requests should once more return the Image/Asset ID in the response with a status code of 200.

You might as well do this:


As far as I know it works with both shirts and decals. ^^
Although, the way you have set it up works fine as well. I just wanted to come up with a maybe quicker method? :slight_smile:

The issue is doing this at runtime, not in Studio. For example someone inputs an ID and you need the asset. At runtime it won’t go from normal URL to asset.

2 Likes

Alright. I thought the issue was something else. Ty for telling. (;

Hello, Can I use this?

If not, then what are alternatives?

Unfortunately as the title states, this API is depreciated due to issues with it. From my own searching you can use the F3X Api which accomplishes the same thing, however you’ll need to dive into the F3X build tools to find the URL to send the request to.

If I have time to look into this soon I may do a rewrite to make it functional again. It didn’t have many requests being made to it so I assumed it didn’t have much use for people.

if anyone needs the width/height of an image, I have an API too: https://plugin-utils.glitch.me/sprite-splitter/imageId

e.g. https://plugin-utils.glitch.me/sprite-splitter/68073547
https://plugin-utils.glitch.me/sprite-splitter/68073547.png

2 Likes

cc @GooierApollo664

The domain for F3X’s asset extraction is https://f3xteam.com/bt/. There are specific endpoints for decals and meshes. Remember to wrap the calls with pcall, as is standard (or should be) when working with the HttpService.

To retrieve an image, you require getDecalImageID with the ID supplied. It returns a number in plain text, so you can return the response directly from the call and use it.

local image = HttpService:GetAsync("http://f3xteam.com/bt/getDecalImageID/decalID")

To retrieve mesh data, it’s getFirstMeshData. It returns a JSON string that includes the fields:

  • bool success
  • number meshID
  • number textureID

For this, you can return the result of JSONDecode on the response of the call. This will give you a table. If success is true, meshID and textureID will be included. You can then use those on the fly.

local meshDataRaw = HttpService:GetAsync("http://f3xteam.com/bt/getFirstMeshData/meshID")
local meshData = HttpService:JSONDecode(meshDataRaw)

if meshData.success then
    print(meshData.meshID, meshData.textureID)
end

If you want to replicate these endpoints and host your own server that can do this, quite sure something in Roblox’s web API should help you out. You could probably run it in the box too with a proxy.

5 Likes

Currently trying to do the same thing myself, however I really dislike the idea of relying on someone else’s web server for a game feature.

So I made some code to do this by subtracting 1 until it finds an asset ID. Don’t get me wrong, I hate the -1 method too. But i’d prefer it over a web server. I ran about 20 tests on some random decals and it worked every time.

function getAssetIdFromDecalId(decalID)
	for i = 0, 10 do
    	if game:GetService("MarketplaceService"):GetProductInfo(decalID-i, Enum.InfoType.Asset)["AssetTypeId"] == 1 then
	    	return decalID-i
	    end
    end
	return 0
end

EDIT:

Ok, turns out that only works on some older decals… (yikes)

Here is an even more hacky way to get it. Again, this is INCREDIBLY inefficient. I cannot state that enough. But I prefer it over using a web server.

function getAssetIdFromDecalId(decalID)
	for i = 0, 50 do
		if game:GetService("MarketplaceService"):GetProductInfo(decalID-i, Enum.InfoType.Asset)["AssetTypeId"] == 1 then
			if game:GetService("MarketplaceService"):GetProductInfo(decalID-i, Enum.InfoType.Asset)["Creator"].Id == game:GetService("MarketplaceService"):GetProductInfo(decalID, Enum.InfoType.Asset)["Creator"].Id then
				return decalID-i
			end
		end
	end
	return 0
end
1 Like

Definitely. While they were neat utilities to have, you should avoid others’ web servers where possible. It’s essentially the same debacle as private modules. You should keep web calls to a minimum itself even if you have a trusted domain or run your own joint.

1 Like

Maybe mainly using web service and using your hack as backup is best option

1 Like

This thread was bumped, so since it’s clearly relevant to people here’s a function that combines all the methods discussed, and falls back on the low-res thumbnail if it needs to. It’ll also resort to a broken image icon if it completely fails.

I use this to let users add images to their tutorial creation in Lua Learning. I don’t want them to have to go to Studio to find their image id, so I let them use the decal ID and this handles it for them.

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

local ImageFailedID			= "rbxassetid://3084222307" -- The typical broken image icon

local function GetImageFromDecal(DecalID)
	local id
	local s,e = pcall(function()
		local p = MarketplaceService:GetProductInfo(DecalID, Enum.InfoType.Asset)
		if p.AssetTypeId == 1 then
			-- It's an image ID, use as is
			id = "rbxassetid://"..DecalID
	
		elseif p.AssetTypeId == 13 then
			-- It's a decal ID, so lets do our best to find the image ID before resorting to the low res decal version
					
			-- Get via F3X proxy (only works on server cuz http)
			local img
			local s,e = pcall(function()
				img = HttpService:GetAsync("http://f3xteam.com/bt/getDecalImageID/"..DecalID)
			end)
				
			if s and img then
				-- F3X worked
				id = "rbxassetid://"..img
				
			else
				-- F3X failed, try the old -1 trick

				local creatorID = p.Creator.Id
				for i = 0, 50 do
					local nextAsset = MarketplaceService:GetProductInfo(DecalID-i, Enum.InfoType.Asset)
						
					if nextAsset.AssetTypeId == 1 then --It's an image ID
						if nextAsset.Creator.Id == creatorID then -- Same creator, so good odds it's the image we need
							id = "rbxassetid://"..(DecalID-i)
							break
						end
					end
				end
					
				if id == nil then
					-- We didn't find it via the -1 so lets use the low-res thumb
					id = "https://www.roblox.com/asset-thumbnail/image?assetId=".. DecalID .."&width=420&height=420&format=png"
						
				end
			end	
		end
	end)

	return id or ImageFailedID
end

-- Simple to use:
ImageLabel.Image = GetImageFromDecal(3955633640)
4 Likes

Wouldn’t recommend, you might experience throttles.

Relevant:

Roblox has actually implemented a solution to this! With the new rbxthumb API you can display any asset in game with just one URL!

This means no more looking through id’s and checking if you have finally found the image. Just insert the decal ID here and it will show up!

rbxthumb://type=Asset&id=DECALID&w=150&h=150

2 Likes

That’s 150x150 compared to the 1024x1024 image.

It literally returns a blur. Useless.

At least this one
https://www.roblox.com/asset-thumbnail/image?assetId=DECALID&width=420&height=420&format=png
gives it in 420x420. Still blurry, not not entirely worthless.

2 Likes

Yup. Added it because it was discussed in the thread.

Do note that I improved the original version that @Naco88 posted.

Their version made 3 calls per loop, with 150 calls worst case. Mine has 1 call per loop, with 51 worst case.

1 Like

Why is Roblox just making simple things so difficult? Why can’t Decals include Image Id?

6 Likes