libvips / lua-vips

Lua binding for the libvips image processing library
MIT License
125 stars 10 forks source link

Using VIPs library and Lua to process pictures #37

Closed hzm199822 closed 6 months ago

hzm199822 commented 3 years ago

To get an original picture from the file, what I want to do is to select a position, cut a rectangle, and make a concave or convex semicircle on the edge of the rectangle, and make this area transparent. Is there an appropriate API or solution?

jcupitt commented 3 years ago

Hi @hzm199822, could you post a sample image showing what you want?

jcupitt commented 3 years ago

For example, this:

#!/usr/bin/luajit

local vips = require "vips"

local im = vips.Image.new_from_file(arg[1], {access = "sequential"})

-- make a transparent square ... just RGBA all 0 (black)
local square = vips.Image.black(64, 64, {bands = 4})

-- insert into the main image
im = im:insert(square, 100, 100)

im:write_to_file(arg[2])

makes a square in an image transparent, eg.:

$ ./try320.lua ~/pics/lion.png x.png

x

Where do you need the semicircle? Do you need a line, or a segment?

hzm199822 commented 3 years ago

![Uploading 1111.png…]()

hzm199822 commented 3 years ago

What I want is not all white, but translucency. Or that piece becomes a watermark

hzm199822 commented 3 years ago

What I want is that this square is just a benchmark. I want to add a semicircle or subtract a semicircle on any two sides of the four sides of the square. Of course, the diameter of the semicircle must be smaller than the side length

hzm199822 commented 3 years ago

What I want is that this square is just a benchmark. I want to add a semicircle or subtract a semicircle on any three sides of the four sides of the square. Of course, the diameter of the semicircle must be smaller than the side length. The translucency on the right side of the image can also be a fuzzy watermark. Then the block on the left side, I hope, is the same as the missing block in the original image, which is equivalent to providing a picture. I need to make two images, one is with watermark, the other is a small piece taken out separately I don't know if luavips can do this for images (add or subtract semicircles on the edges of rectangles)

jcupitt commented 3 years ago

The square in the lion only looks white because the page background is white. Try opening the image in a new tab.

You can overlay complex shapes with composite. You give it an RGBA image, one of the PDF blending modes (eg. over) and a position.

Could you upload some test images? It would save me making them. Just drag the images into the text box.

hzm199822 commented 3 years ago

huangzhiming zm.huang@ucloud.cn

签名由 网易邮箱大师 定制

On 11/4/2020 15:58,John Cupittnotifications@github.com wrote:

The square in the lion only looks white because the page background is white. Try opening the image in a new tab. You can overlay complex shapes with composite. You give it an RGBA image and one of the PDF blending modes (eg. over) and a position. Could you upload some test images? It would save me making them. Just drag the images into the text box. — You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or unsubscribe.

jcupitt commented 3 years ago

Composite example:

#!/usr/bin/luajit

vips = require 'vips'

local image = vips.Image.new_from_file(arg[1], {access = "sequential"})
local overlay = vips.Image.new_from_file(arg[2], {access = "sequential"})

-- composite the overlay at 50, 20 using 'over' blend mode
image = image:composite(overlay, "over", {x = 50, y = 20})

image:write_to_file(arg[3])

Generates:

x

hzm199822 commented 3 years ago

I mainly want to extract a figure from the original image, then save it, and change the extracted part of the original image into translucent or other

hzm199822 commented 3 years ago

It's important to extract this step, but it seems to me that the API can only extract simple rectangles

jcupitt commented 3 years ago

You can apply masks if you want more complex shapes.

Post a set of sample images and I'll have a go.

hzm199822 commented 3 years ago

like this?

huangzhiming zm.huang@ucloud.cn

签名由 网易邮箱大师 定制

On 11/4/2020 17:07,John Cupittnotifications@github.com wrote:

You can apply masks if you want more complex shapes. Post a set of sample images and I'll have a go. — You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or unsubscribe.

jcupitt commented 3 years ago

Use the github website and drag images into the text box.

hzm199822 commented 3 years ago

![Uploading 图片.png…]()

jcupitt commented 3 years ago

You need to wait for the upload to finish before pressing Comment.

hzm199822 commented 3 years ago

图片

hzm199822 commented 3 years ago

OK, now it's OK. My goal is very simple, that is to get such a shape from the original image rather than just a simple rectangle. After saving this shape, I will do some operations on the original image, such as translucency, or other things. I can now extract rectangles and darken them myself, but I don't know if there is such an API to support my goal.

jcupitt commented 3 years ago

Ah, like a jigsaw, I wondered.

Yes, it should be easy. Do you have that shape as a PNG?

hzm199822 commented 3 years ago

8 square_back background

hzm199822 commented 3 years ago

What I want to do is JPG, the encoding format of JPG is simpler than PNG, and the operation time should be shorter

jcupitt commented 3 years ago

I mean, do you have a PNG for the jigsaw piece? It would save me drawing it.

hzm199822 commented 3 years ago

图片

hzm199822 commented 3 years ago

图片

hzm199822 commented 3 years ago

like this?

jcupitt commented 3 years ago

I found this sample:

jigsaw

Example code:

#!/usr/bin/luajit

vips = require 'vips'

local image = vips.Image.new_from_file(arg[1], {access = "sequential"})
local mask = vips.Image.new_from_file(arg[2], {access = "sequential"})

-- the position we place the piece
left = 200
top = 100

-- get just the alpha from the mask
alpha = mask:extract_band(3)

-- image pixels
rgb = image:crop(left, top, mask:width(), mask:height())

-- brighten 50%
rgb = rgb * 1.5

-- attach the mask as the alpha channel
overlay = rgb .. alpha

-- composite back
image = image:composite(overlay, "over", {x = left, y = top})

image:write_to_file(arg[3])

I can run like this:

$ ./try320.lua ~/pics/Gugg_coloured.jpg ~/pics/jigsaw.png x.jpg

To make this:

x

hzm199822 commented 3 years ago

no...

hzm199822 commented 3 years ago

What I want to do is to get a jigsaw block from the original image, not a rectangle, because I need this puzzle block to do some operations. This jigsaw block comes from the original picture, and the position obtained from the original image is different each time

jcupitt commented 3 years ago

Sorry, I still don't understand what you want to do.

Are you trying to hide or remove the watermark?

hzm199822 commented 3 years ago

4fe01a4819e02fbfce70f3cd0dbbe491

hzm199822 commented 3 years ago

local vips = require"vips.vips"

local background = "/home/hzm/hzm/vips/8.jpg" local back = vips.Image.new_from_file(background) math.randomseed(tonumber(tostring(os.time()):reverse():sub(1,7))) local s = os.clock() local random_left = math.random(512,914) local random_top = math.random(1,626) local random_length = math.random(81,100) local square_black = vips.Image.black(random_length,random_length,{bands = 3})

local square_back = vips.Image.crop(back,random_left,random_top,random_length,random_length) back = back:insert(square_black,random_left,random_top) back:write_to_file("/home/hzm/hzm/vips/background.jpg") square_back:write_to_file("/home/hzm/hzm/vips/square_back.jpg") local e = os.clock() print("used time:"..e-s.."seconds")

hzm199822 commented 3 years ago

thsi api crop Help me get a rectangle from the original, but I want to get a puzzle block instead of a rectangle. What should I do? I've thought about getting rectangles and two semicircles, but I haven't found the API for getting semicircles

jcupitt commented 3 years ago

You just get a rectangle and then apply an alpha to cut the exact shape, like in my example above.

hzm199822 commented 3 years ago

I don't think I understand this API properly :extract_band

jcupitt commented 3 years ago

Example:

#!/usr/bin/luajit

vips = require 'vips'

local image = vips.Image.new_from_file(arg[1])
local mask = vips.Image.new_from_file(arg[2]) 

-- the position we take the piece from
from_left = math.random(0, image:width() - mask:width())
from_top = math.random(0, image:height() - mask:height())

-- the position we put the piece back
from_left = math.random(0, image:width() - mask:width())
from_top = math.random(0, image:height() - mask:height())

-- get just the alpha from the mask
alpha = mask:extract_band(3)

-- image pixels
pixels = image:crop(from_left, from_top, mask:width(), mask:height())

-- brighten and darken 50%
brighter = pixels * 1.5
darker = pixels * 0.5

-- attach the mask as the alpha channel
brighter = brighter .. alpha
darker = darker .. alpha

-- composite back
image = image:composite(darker, "over", {x = from_left, y = from_top})
image = image:composite(brighter, "over", {x = to_left, y = to_top})

image:write_to_file(arg[3])

To make:

x

I expect you'd like a shadow as well. The easiest way is to draw the shadow on the mask, but you could also compute one with a convolution.

jcupitt commented 3 years ago

If you have a three-band image (eg. RGB) you can extract a band like this:

g = rgb:extract_band(1)

Now g is a one-band image (just the green). Bands number from zero.

hzm199822 commented 3 years ago

I'd like to know how you changed the rectangle into this puzzle. Instead of drawing this puzzle in advance, you took it directly from the original picture

hzm199822 commented 3 years ago

You mean, let me get a rectangle from the original picture and then turn it into a puzzle?

hzm199822 commented 3 years ago

The most important thing is to get it directly from the original drawing, not draw it yourself.

jcupitt commented 3 years ago

I just took the alpha channel from that jigsaw PNG.

You can draw yourself, of course, if you have something like an SVG of the shape.

hzm199822 commented 3 years ago

Of course, I know that I can draw by myself, but the effect I want is to take it directly from the original image, because the shape and content are different each time. Do I have to draw again every time? Scholar, can you understand what I mean?

hzm199822 commented 3 years ago

8 square_back background

hzm199822 commented 3 years ago

local vips = require"vips.vips"

local background = "/home/hzm/hzm/vips/8.jpg" local back = vips.Image.new_from_file(background) math.randomseed(tonumber(tostring(os.time()):reverse():sub(1,7))) local s = os.clock() local random_left = math.random(512,914) local random_top = math.random(1,626) local random_length = math.random(81,100) local square_black = vips.Image.black(random_length,random_length,{bands = 3})

local square_back = vips.Image.crop(back,random_left,random_top,random_length,random_length) back = back:insert(square_black,random_left,random_top) back:write_to_file("/home/hzm/hzm/vips/background.jpg") square_back:write_to_file("/home/hzm/hzm/vips/square_back.jpg") local e = os.clock() print("used time:"..e-s.."seconds")

hzm199822 commented 3 years ago

I don't believe it. You don't understand what I need

jcupitt commented 3 years ago

Instead of

local square_back = vips.Image.crop(back,random_left,random_top,random_length,random_length)

You can write:

local square_back = back:crop(random_left,random_top,random_length,random_length)

No, I don't understand what you mean :-(

Do you want to detect a jigsaw shape in the original image somehow? Do you know where it is, or do you need to search for it? Is it always the same shape, or do you need to detect any kind of jigsaw shape?

If you can give a clear explanation of what you need, perhaps I can help.

hzm199822 commented 3 years ago

The original image is a normal 320 * 160 rectangle. I want to cut the next puzzle shape from the original image. I don't know where I need to cut, because I can use random numbers to determine the coordinates I want to cut. I define their shape as a rectangle and two semicircles, which can be concave or convex. I need to cut it off from the original.

hzm199822 commented 3 years ago

cf271ab9834f819b3a649dd07976dc26

hzm199822 commented 3 years ago

You know, VIPs provides cuts that I can only find clipping rectangles

hzm199822 commented 3 years ago

If there is a semicircle, I think I can cut it twice. The first time I cut the rectangle, the second time I cut two semicircles on the edge of the rectangle, and then I can cut the combination again to achieve the desired effect

hzm199822 commented 3 years ago

When I combine these parts, he is a puzzle shape. I then turn the puzzle into black or white or transparent, and put it on the original picture. That's all right