Jump to content

[SOLVED | 1.12/1.13] Get color from texture


Brickmotion

Recommended Posts

I'm trying to obtain the color value of an item's texture, more specifically from a specific pixel, to colorize tools in that color. I already know how to apply a color to an item (the way it's done on spawn eggs), yet I can't find anything on how to obtain the color value from another item for any version since the introduction of the JSON model system. As I want to apply the colors from the ingot that the tool is made of rather than keeping extensive lists of each color value, does anyone know how to achieve this? I know that it's possible somehow, as it is apparently used by Technomancy for refined ores, but I can't figure out how it is done there.

Edited by Brickmotion
Link to comment
Share on other sites

What exactly are you trying to do?

If you want to obtain a color of an item you can use ItemColors#colorMultiplier. Mind you this will return a white color if the item has no IItemColor associated with it.

If you want to get the color from the texture you would need to somehow get the file that is responsible for the sprite, read it(to a BufferedImage perhaps) and then get the color of the pixel you want(or all pixels and average the color)(for a BufferedImage it would be BufferedImage#getRGB). Mind you that this approach is rather expensive. Alternatively you could read the pixels at specific coordinates on a texture using GL11.glReadPixels. The texture could be grayscaled to later be colored by an IItemColor. For this approach you would need to know the coordinates of the pixel on the sprite map though so you would need a sprite in the first place.

 

Also the mod you've linked is open source. You could see how they did it.

And keeping a list of each color value for each ingot is not that bad. It is actually the most sensical approach. It's just an integer per ingot you wish to register after all.

And I have no idea why you are implying that you are modding for 1.13. Forge for 1.13 isn't out yet.

Link to comment
Share on other sites

2 minutes ago, V0idWa1k3r said:

What exactly are you trying to do?

If you want to obtain a color of an item you can use ItemColors#colorMultiplier. Mind you this will return a white color if the item has no IItemColor associated with it.

If you want to get the color from the texture you would need to somehow get the file that is responsible for the sprite, read it(to a BufferedImage perhaps) and then get the color of the pixel you want(or all pixels and average the color)(for a BufferedImage it would be BufferedImage#getRGB). Mind you that this approach is rather expensive. Alternatively you could read the pixels at specific coordinates on a texture using GL11.glReadPixels. The texture could be grayscaled to later be colored by an IItemColor. For this approach you would need to know the coordinates of the pixel on the sprite map though so you would need a sprite in the first place.

 

Also the mod you've linked is open source. You could see how they did it.

And keeping a list of each color value for each ingot is not that bad. It is actually the most sensical approach. It's just an integer per ingot you wish to register after all.

And I have no idea why you are implying that you are modding for 1.13. Forge for 1.13 isn't out yet.

I put 1.13 in the title as Forge 1.13 could come out rather soon and I didn't know how fast someone would reply.

I do know what pixel of the texture I want to take the color from, as I want to take it from an ingot texture, which in my case is always shaped the same. Keeping a list is really inpractical for me, as my mod has roughly 200 ingots that I want to get the colors from, and need colors from at least 2 different pixels so the tools can match the ingot (one color results in too many tools looking to similar). I think the GL11.glReadPixels method seems to be the most useful, I'll try to look into it.

Link to comment
Share on other sites

this is a bit different, but you could also just have a specific texture in the model that you can retexture. You can retexture your model with Model#retexture(textureName, newTextureResourceLocation). You should really be defining everything in JSON so that Data Packs and Resource Packs can modify stuff.

About Me

Spoiler

My Discord - Cadiboo#8887

My WebsiteCadiboo.github.io

My ModsCadiboo.github.io/projects

My TutorialsCadiboo.github.io/tutorials

Versions below 1.14.4 are no longer supported on this forum. Use the latest version to receive support.

When asking support remember to include all relevant log files (logs are found in .minecraft/logs/), code if applicable and screenshots if possible.

Only download mods from trusted sites like CurseForge (minecraft.curseforge.com). A list of bad sites can be found here, with more information available at stopmodreposts.org

Edit your own signature at www.minecraftforge.net/forum/settings/signature/ (Make sure to check its compatibility with the Dark Theme)

Link to comment
Share on other sites

So I found a solution, for anyone else wanting to do a similar thing: I coded a function to get three different color values from the ingot (you could just as well do more by just adding coordinates to the coordinate array) that is used for each ingot in an ingot list once in the preInit() section and fills an array with the values that can be used in the class implementing IItemColor:

 

public int[] getColors(String name){
		InputStream is;
		BufferedImage image;
		int[] res = {0,0,0};
		int[] texture;
		try {
			String itemID;
			itemID = Reference.MOD_ID + ":textures/items/" + name + "_ingot.png";
			is = Minecraft.getMinecraft().getResourceManager().getResource((new ResourceLocation(itemID))).getInputStream();
		    image = ImageIO.read(is);
		}catch(IOException e){e.printStackTrace();return res;}
		int[][] coords = {{4,5,0},{8,10,6}};
		for (int j = 0; j < 3; j++) {
			texture = image.getRaster().getPixel(coords[0][j], coords[1][j], new int[4]);
			res[j] = new Color(texture[0],texture[1],texture[2]).getRGB();
		}
		return res;
	}

This code returns a three element integer array with the RGB values of the pixels [4,8], [5,10] and [0,6] from the texture defined as the name. As all my ingot names are saved in an array, I simply run through that array in a for loop and save the three result integers as array elements in a global array usable by all classes. Should the texture not exist, the function will return {0,0,0}, which results in the tools being colored black (though this could be changed to any color by simply changing the initial values of res to different numbers).

 

I hope I could help anyone trying to do something similar to what I did.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.