Bulk creation + edit images - image-processing

I currently use photoshop + datasets to automatically create CTA buttons for testing on a clients website. The dataset often contains text and other changes like underline or background colour, as well as alignment and font formatting.
Typically these can run into the thousands, which photoshop handles very well but the task is technical and not graphical. For me photoshop is overkill for the task.
Is anyone aware of a solution that is more code-friendly? I am currently playing around with canvas on HTML and fabric.js. This allows me to manipulate a template image, and I hoping I can pipe in code to create a number of .png output images.

Canvas would be well suited to your automation
First, create a base .png and then programmatically alter it in thousands of ways.
Save the results to appropriately named .png files.
You could even create an on-screen viewer that dynamically creates thousands of variations. The client(s) could browse the dynamically created images and select the variations that interest them. That would eliminate the need for thousands of saved files.
Here are just a start of canvas commands you can use to automate:
Apply text:
context.font("italic 14pt Verdana");
context.textAlign = textAlign; // left|right|center
context.fillText("anyText", x,y);
Underlines are just a bit trickier:
// use measureText to get the text width
var textWidth =context.measureText(text).width;
// 1-time only, pre-calculate all the “Y” underline offsets for each font you use
var ULOffset=lookupULOffset(font,fontSize);
context.moveTo(x,y+ULOffset);
context.lineTo(textWidth,y+ULOffset);
context.stroke();
Change background color or anything else that you've created a sub-layer for!
Like Photoshop Canvas has an excellent set of compositing operations.
Source-over
Source-in
Source-out
Source-atop
Lighter
Xor
Destination-over
Destination-in
Destination-out
Destination-atop
Darker (this has been deprecated for some reason??)
You also can apply an alpha when drawing a layer as well as an alpha while drawing any canvas shapes.
In addition, check online for many image filters that have been created for canvas.
And that's just be beginning...
Happy Automating!

Related

How to recolor an image on specific area?

I'm trying to create an iOS recoloring app (this is my reference), and i need to know how recolor some portion of the image when user taps on a given area. All the loaded pictures will be black/white initially.
Is there any prebuilt library? Or which graphics framework should i use?
Any help will be appreciated.
If what you are looking for is adding/replacing the colour within a certain shape and edges are really important (as in the example) then you should be looking into vectorised drawing.
What this means is every shape in your image would have an actual object representation in your code, and you could easily interact with that object to do whatever you want (i.e. tap gestures to change colour, zoom etc.).
This however, means that you can't simply use .jpeg images, and you need to use images in vector format, such as .svg or CorelDraw.
As a reference, check out SVGKit, which is an excellent library for working with SVG images.

How to create UIButton with custom shape in Swift?

I need to create button like this
and the change the background programmatically like this
and like this
I can not use images for different states of a button because each time I have different text on it.
What to start from ? I tried to understand CoreGraphics and CoreAnimation but there is too small amount of examples and tutorials so my attempts didn't give me any success.
You can, and should, use an image for this. UIKit has a method resizableImageWithCapInsets that creates resizable images. You feed it a minimum sized image and the system stretches it to fit the desired size. It looks like your image is fixed in height, which is good since you can't do smooth gradients with this technique.
UIButtons are composed of a background image and title text, so you can use an image for the background shapes (setBackgroundImage(_:forState:)), and then change the text using setTitle(_:forState:).
However, you can still use Core Graphics for this, and there are benefits to doing so, such as the fact that it reduces the number of rendered assets in your app bundle. For this, probably the best approach is to create a CAShapeLayer with a path constructed from a UIBezierPath, and then render it into a graphics context. From this context, you can pull out a UIImage instance, and treat it just the same as an image loaded from a JPEG or PNG asset (that is, set it as the buttons background image using setBackgroundImage(_:forState:)).

Highcharts: backgroundColour "layers"?

At present I'm generating a chart based on a bunch of user-selected options, and this is rendered on the server to generate a png output file. The generated png chart is then displayed on the user's system, over an underlying system background.
Where the plotBackgroundColor of the chart has some opacity, the user's underlying system background will of course show through, and will influence how the chart appears.
That's all fine, because the user has complete control over both the highcharts plotBackgroundColor and the system background colour.
But now I want to generate a chart that is "free standing", with a solid background colour (no opacity) which represents exactly how the chart appears when over the system background. That way, I can display that chart on any system, to give a true picture of what the user is seeing, regardless of the system background colour in the target device.
I do have access to the user's system background colour (it's either a bitmap, or I can just extract the "dominant" colour somehow and use that as a solid colour instead if it's easier).
So using the concept of layers, this would be like merging the highcharts plotBackgroundColor with a solid colour that represents the system background colour, and using that as plotBackgroundColor instead.
Or maybe there's a way to change an underlying background "browser" colour that is used in the highcharts renderer, independent of plotBackgroundColor?
I'm sure this must be possible somehow?
One way of doing this, and it's what I'm doing until someone posts a better answer, is just to manually combine each backgroundColor value with the underlying system canvas colour, using the method described at https://stackoverflow.com/a/10782314/4070848. This is basically just laying one colour over the other, and using an algorithm to determine the combined colour based on the respective opacities and rgb values.
I check whether the backgroundColor is a plain colour or a linear/radial gradient, and if the latter then I combine each of the stop colours separately with the underlying colour and reconstruct the gradient based on the merged stop colours.
Seems to work OK, but maybe there's an off-the-shelf method, or maybe someone can tell me how to do it better...!

Display secondary underlying image on a Imagelist?

I have a Image list assigned to a listview to display transparent images.
There is a slight issue with this regarding some transparent images that are added, and that is they are sometimes hard to see/find in the listview.
See this example image:
You will notice that the images (noticeably the mouse) is barely viewable, infact if a empty image was added you would not even see it, the number captions come to the rescue here to show there is something actually there.
But I would like to make the images visually easier to see. I thought maybe having another image underneath the transparent images would work - of course though it could not affect the actual image.
So with that in mind, I made a bitmap of a chessboard grid:
I feel this would be the most suitable way of representing transparent areas of the images just like Paint.NET etc does.
To further illustrate this example I have modified the original image to show how it would look, if we had the chessboard bitmap as the underlay image:
Having the chessboard there would indicate there is a list item there in the first place, and the bitmap of the chessboard grid could be darker or an altogether different kind of image. As I said earlier if there was no image you would see nothing at all, so better to show an empty chess grid or other bitmap than nothing.
So, how can I display a second image underneath the original images using a imagelist to give a result similar to the example above? The underneath image could be anything - just another loaded bitmap for example.
If you store the chessboard as the first image (with index 0) and make the overlay image from the current image in the OnGetImageIndex event handler, it will do what you want to. However I'm not sure how efficient is to make the overlay image every time the event is fired.
procedure TForm1.ListView1GetImageIndex(Sender: TObject; Item: TListItem);
begin
// make the overlay (with overlay index 1) from the
// image with index Item.Index + 1
ImageList1.Overlay(Item.Index + 1, 1);
// use the first image from the list as a background
Item.ImageIndex := 0;
// and assign just created overlay index for overlay
Item.OverlayIndex := 1;
end;
I seems that what you need is a TImageList with extra capabilities.
As a starting point, I suggests you to consider TImageListEx described in the book Inside Delphi 2006
Excerpt:
The TImageListEx component is a TImageList descendant that can use the
images from another image list to generate disabled images, which can
be used on toolbars and other user interface elements.
The TImageListEx component is a TImageList descendant that can use the
images from another image list to generate disabled images, which can
be used on toolbars and other user interface elements.
There are several benefits of the TImageListEx component:
It eliminates the need for creating disabled glyphs.
It eliminates the need for adding the disabled glyphs to an additional TImageList component at design time.
It can drastically reduce the size of the .dfm file and of the entire application, especially in large applications that use a lot of
glyphs.
It's extremely fast, taking only milliseconds to disable all images in an image list, even when there are number of images.
It's extremely lightweight. (If you add it to an application that already uses the standard TImageList component, it won't increase the
size of the executable at all, and if you add it to an application
that doesn't use the standard TImageList component, the overhead is
only 2 KB.)
It's far from your requirements but yet detailed enough to show how to extend TImageList.

iOS: Smooth button Glow effect by blending between images

I am creating a custom button that needs to be able to glow to a varying degree
How would I use these pictures to make a button that 'glows' the diamond when it is pressed, and have this glow gradually fade back to inert state?
I want to churn out several different colours of diamond as well... I am hoping to generate all different coloured diamonds from the same stock images presented here.
I would like to get my head around the basic methods available, in enough detail that I can see each one through and make a decision which path to take...
My tangled efforts so far... ( I will delete all of this, or move it into possibly several answers as a solution unfolds... )
I can see 3 potential solution paths:
GL
it looks as though GL has everything it takes to get complete fine-grained control over the process, although functions exposed by core graphics come tantalisingly close, and that would save several hundred lines of code spread over a bunch of source files, which seems a bit ridiculous for such a basic task.
core graphics, and core animation to accomplish the blending
documentation goes on to say
Anything underneath the unpainted samples, such as the current fill color or other drawing, shows through.
so I can chroma-key mask the left image, setting {0,0,0} ie Black as the key.
this at least secures a transparent background, now I have to work on making it yellow instead of grey.
so maybe I could have started instead with setting a yellow back colour for my image context, then use some CGContextSetBlendMode(...) to imprint the diamond on the yellow, THEN use chroma-key masking to get a transparent background
ok, this covers at least getting the basic unlit image on-screen
now I could overlay the sparkly image, using some blend mode, maybe I could keep it in its current greyscale state, and that would just boost the colours of the original
only problem with this is that it is a lot of heavy real-time blending
so maybe I could pre-calculate every image in the animation... this is looking increasingly mucky...
Cocos2D
if this allows me to set the blend mode to additive blending then I could just composite the glowing image over the original image with an appropriate Alpha setting.
After digging through a lot of documentation, the optimal solution seems to be to use core graphics functions to get the source images into a single 2-component GL texture, and then use GL to blend between them.
I will need to pass a uniform value glow_factor into the shader
The obvious solution might seem to simply use
r,g,b = in_r,g,b * { (1 - glow_factor) * inertPixel + glow_factor * shinyPixel }
(where inertPixel is the appropriate pixel of the inert diamond etc)...
it looks like I would also do well to manufacture my own sparkles and add them over the top; a gem should sparkle white irrespective of its characteristic colour.
After having looked at this problem a little more, I can see several solutions
Solution A -- store the transition from glow=0 to glow=1 as 60 frames in memory, then load the appropriate frame into a GL texture every time it is required.
this has an obvious benefit that a graphic designer could construct the entire sequence and I could load it in as a bunch of PNG files.
another advantage is that these frames wouldn't need to be played in sequence... the appropriate frame can be chosen on-the-fly
however, it has a potential drawback of a lot of sending data RAM->VRAM
this can be optimised by using glTexSubImage2D; several frames can be sent simultaneously and then unpacked from within GL... in fact maybe the entire sequence. if this is so, then it would make sense to use PVRT texture compression.
iOS: playing a frame-by-frame greyscale animation in a custom colour
Solution B -- load glow=0 and glow=1 images as GL textures, and manually write shader code that takes in the glow factor as a uniform and performs the blend
this has an advantage that it is close to the wire and can be tweaked in all sorts of ways. Also it is going to be very efficient. This advantage is that it is a big extra slice of code to maintain.
Solution C -- set glBlendMode to perform additive blending.
then draw the glow=0 image image, setting eg alpha=0.2 on each vertex.
then draw the glow=1 image image, setting eg alpha=0.8 on each vertex.
this has an advantage that it can be achieved with a more generic code structure -- ie a very general ' draw textured quad / sprite ' class.
disadvantage is that without some sort of wrapper it is a bit messy... in my game I have a couple of dozen diamonds -- at any one time maybe 2 or 3 are likely to be glowing. so first-pass I would render EVERYTHING ( just need to set Alpha appropriately for everything that is glowing ) and then on the second pass I could draw the glowing sprite again with appropriate Alpha for everything that IS glowing.
it is worth noting that if I pursue solution A, this would involve creating some sort of real-time movie player object, which could be a very useful reusable code component.

Resources