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

:thinking:

My understanding was the server could insert anything that the place owner owns OR Roblox’s official account owns. Not both are necessary. Unless it changed? :man_shrugging:

No, it hasn’t changed. This is correct. Only assets you or Roblox own can be inserted. Free assets still have to be owned, otherwise they’ll return an HTTP 403 error as per ownership checks.

So long as it’s in your inventory, it’s usable.

1 Like

Isn’t it assets you, ROBLOX or Games own? I remember reading that somewhere.

No. Games is a separate Roblox account utilized by Roblox but their assets are on the same level as a regular user’s. Only the Roblox account (ID 1) has elevated permissions across all assets.

My apologies. It seemed like you were saying OP shouldn’t have made this since nobody would use it and it could be used to infringe copyright.

1 Like

Not at all. All I’m saying is that personally, I can’t find large amounts of use cases for this since there are not a hankering amount of games that use user input for decals nowadays, but this is a cool creation. Its an awesome web trinket that’s like the InsertService workaround but not exactly it. It’s just how many people will use it and what it’s used for is my concern.

OP did say it was for personal use but he was releasing for anyone who wants to use it anyway.

2 Likes

[UPDATE]: Fixed error responses for image not existing when an invalid decal ID was provided. Will now properly send a 404.

[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:
https://twitter.com/Maelstronomer/status/850316111132405762
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