[Open Source] Image Clipping Module

One of my smaller projects, but useful enough to share.

This module is used to quickly create an image with a clipping mask.

It works using ViewportFrames, MeshParts, and Decals.

The module gives you those top images.
With a tiny tweak, I made it show what it’s doing on the bottom row. It places your image as a Decal onto a MeshPart, and puts that into a ViewportFrame. Once it’s done, nothing ever moves, so it’s roughly the same performance as ImageLabels.

API:

local ImageMask    = require(script.ImageMask)
local ClippedImage = ImageMask.new(ImageID, Type) --Returns the ViewportFrame

Example:

local ImageMask = require(script.ImageMask)

local ImageID   = "https://www.roblox.com/headshot-thumbnail/image?userId=".. game.Players.LocalPlayer.UserId .."&width=420&height=420&format=png"

local ClippedImage = ImageMask.new(ImageID, "Circle")
    ClippedImage.Size = UDim2.new(0.3,0,0.3,0)
    ClippedImage.SizeConstraint = Enum.SizeConstraint.RelativeYY
    ClippedImage.Parent = script.Parent

Out of the box, it comes with 5 masks types:
Circle, Rhombus, RoundedSquare, Star, Triangle
To add your own mask, simply create your MeshPart (Top surface is what gets displayed, so model accordingly) and place it inside the Module. Give it a unique name, and then input that name as the Type parameter.

Super simple to use, I hope you enjoy!

Module:

UncopylockedPlace:

100 Likes

This topic was automatically closed after 1 minute. New replies are no longer allowed.

Holy hecc yes this is good. Thank you so much! I’ll be using this for sure in the future :smile:

2 Likes

Seems cool. I’ll try this when i want to add PFPs to my game(s).

1 Like

Very nice job, never thought this was possible!

3 Likes

Looks great! I will be using this for sure soon!

1 Like

Apparently, this has some extremely unpredictable behavior. I won’t report it as a bug yet, in case it’s on my end.

image

Sometimes, the image will be rendered with some strange triangular distortion. (Look at his neck) The mesh it is displayed on is only a single face, no odd triangle there for it to do this.

There’s no repro for this bug, as it happens randomly, and only a small percent of the time. The way I found it was by creating 1000 images in a stress test, and instead found that quite a few of them had this weird bug despite being created identically by the same looped code.

Anyone have any ideas?

2 Likes

I am having this same issue, am trying to find source of this bug, if/once I do I will report back here.

1 Like

How did you decide on it being 62 degree FOV?
I thought it should be 58 because

print(math.atan(.5/.9)*2*math.deg(1))--math.atan(faceSize/2/distanceFromCameraToFace)*2*math.deg(1)

62 fits the 1x0.2x1 MeshPart (with a tiny bit of extra space just in case).

I picked it just by doing a loop of numbers 20-130 and picked the one I thought looked best. Feel free to tinker with it and show me what you come up with!

2 Likes

Why not move the camera instead of tweaking the FOV? I’ve found that moving the camera gives more precise control over the edges. Getting the height you need to move to is surprisingly simple:

RADIUS / math.tan(math.rad(FIELD_OF_VIEW) / 2)

This is what I used in my implementation of this a while back.

2 Likes

Super Awesome! I am glad someone eventually made this. To be perfectly honest, this is something Roblox should have implemented themselves a long time ago.

This is a great method, and I’ll tinker and see how I can use this to allow a wider range of customization. Thanks for sharing!

Edit: I now use this method, and all original files have been updated.

I want to support non-square images. Currently, any non-square image gets stretched, as Decals do not support any other form of image wrapping.

The downside to Decals on MeshParts is that they distort to the part’s size. Thanks to the method shared by @Reselim, I can easily modify the code to handle parts of varying sizes, and then I’d simply have to size the mesh based on the image’s aspect ratio.

However, I don’t know how to get image aspect ratio from an asset id. Is there a method or API call that I am unaware of, or will I have to add another argument .new() in which the user passes the ratio.
I’d much prefer the module handles it automatically, so please let me know!

EDIT:
Apparently, you have to use external HTTP work to get it. I’ve found this amazing plugin by @evaera that gets the image dimension with an HTTP request.
However, HTTP requests can only be handled by the server, whereas this module is client-sided. To get around this, I’d have to create a remote event system. It’s not complicated, but it would transform this project from a simple plug-n-play module to a system requiring some setup.

I made a version using some of @Quenty’s modules that I rewrote. It has support for Promises!

ImageMask.rbxm (20.3 KB)

2 Likes

Thank you so much! This was really simple to carry out and I’m now using it in my upcoming Halloween game for a dialog ui.

1 Like