Tile more than 9 images with Cocoa - cocoa

I want to draw 15 images in drawRect: but the biggest I could find was NSDrawNinePartImage() I want 4 corners, top/bottom fill, and 3 rows between them (two side fills and a center fill)
What is recommended here? NinePart + 2 * ThreePart? Or something else?

NSDrawNinePartImage is for drawing a single thing that's divided into nine aligned sections like a tic-tac-toe/noughts-and-crosses board.
The primary use case for that is a rounded-rectangle UI element, such as a button. You'd have four fixed-size corners, four uniaxially-stretchable sides, and one biaxially-stretchable center.
That doesn't fit with what you're describing. Three center columns?
If the two extra columns should be fixed in horizontal size, then put each end's images together into a single image per corner and per side. Then use NSDrawNinePartImage as normal.
If the two extra columns are part of the center column and so should be horizontally stretchable, then I suggest that you use NSDrawThreePartImage from inside an NSCustomImageRep subclass and use an instance of that subclass for each of three center-column part images. Then use NSDrawNinePartImage as normal.
(Substitute “rows” for “columns” and “vertically” for “horizontally” in the previous three paragraphs if you want.)

Related

How to avoid label of 2 layers in layer group overlaps in geoserver?

I have been create 2 layers with a text label of each other. When I add that 2 layers in a layer group, I see that 2 labels of 2 layers overlaps like in image below:
Anyone know how to avoid that problem.
WMS requests are completely independent of each other, so GeoServer can't tell that you intend to display the two layers on top of each other. Therefore there is nothing it can do automatically to prevent your two labels being on top of each other.
You can avoid this by combining the two layers into one request, this would need to be done in your client somehow.
Alternatively, you could modify the two SLD files that generate your labels to add a positive and negative offset from the label position so that the two labels are less likely to overlap.

How do I make the plot generated marker more noticeable?

I have the coordinate indicating the start of each letter within a word. I have set the plot function to make a red circle at that coordinate like so:
The problem is that the paper I am adding this image to has a structure of 2 columns per page. And when I add 2 of the above image to the same column, the circles become very small and difficult to notice.
I tried instead of circles to make triangles or pentagrams. I get the same result, they become too small to distinguish.
How can I make this more distinguishable? Especially when its printed in black and white.
You can change the marker size of the markers, and\or overlay two different markers one of the other. For example:
x=1:100;
y=rand(1,100);
plot(x,y); hold on
n=20:20:60;
plot(x(n),y(n),'r+','MarkerSize',30,'LineWidth',2);
plot(x(n),y(n),'ro','MarkerSize',15,'LineWidth',2);
There are many other degrees of freedom you can use to add \ change to this. It is a very basic question that you could have answered yourself if you read the documentation of plot in TMW website.

Autolayout - equal distribution of 6 views

I want to have 6 objects (buttons) laid out inside one view. They should, however, follow some constraints:
Two top buttons should have the same vertical distance from superview (A)
Two bottom - the same (C)
Two in the middle should have their centers at the superview's center line
The vertical distances between all buttons (E) should be the same
and last but not least - the buttons should be square (so the width and height should be the same)
A = C
B = D
Is it possible to have this effect just in the IB, or should I use some additional code for the constraints?
This is a logical request, but constraints are defined using the attributes of views, but cannot not be defined in relation to other constraints. That having been said, there are a number of approaches:
Layout guides: An approach which doesn't require predetermining the any spacing is to have UILayoutGuide objects or, if using iOS versions before 9, just use hidden views, i.e. views with clear background or alpha of zero, in between the buttons.
The idea is to add these layout guides with addLayoutGuide (or add invisible views with addSubview if supporting iOS versions predating iOS 9) in between your six buttons as "spacers", and define the spacers to be the same size as each other, and with constraints between the spacers, the superview, and the buttons that will go in between the spacer. Once you lay that out (showing the horizontal spacer views in blue, vertical ones in red, just so you can see them):
The equivalent VFL for the constraints for those red UIView objects, called vspacerX, would be:
H:|[vspacer1][button1(100)][vspacer2(==vspacer1)][button2(==button1)][vspacer3(==vspacer1)]|
H:|[vspacer1][button3(==button1)][vspacer2][button4(==button1)][vspacer3]|
H:|[vspacer1][button5(==button1)][vspacer2][button6(==button1)][vspacer3]|
And constraints on the blue UIView objects, called hspacerX, like:
V:|[hspacer1][button1(100)][hspacer2(==hspacer1)][button3(==button1)][hspacer3(==hspacer1)][button5(==button1)][hspacer4(==hspacer1)]|
V:|[hspacer1][button2(==button1)][hspacer2][button4(==button1)][hspacer3][button6(==button1)][hspacer4]|
You don't have to use VFL to define these constraints, as any way you define these constraints will work, but it's just a concise format for describing the collection of constraints that I employed.
Anyway, when the view is rendered with those layout guides (or invisible views), it yields evenly spaced buttons like so:
Another approach is to have six "container" views, that would look like:
The equivalent VFL for these six container UIView objects might look like:
H:|[container1][container2(==container1)]|
H:|[container3(==container1)][container4(==container1)]|
H:|[container5(==container1)][container6(==container1)]|
V:|[container1][container3(==container1)][container5(==container1)]|
V:|[container2(==container1)][container4(==container1)][container6(==container1)]|
You can then add your buttons to that, centering one on each of the six little containers and then make your containers clear:
This works, too, but just a slightly different spacing (where the margins are half of the spacing between the views, whereas the other approach keeps the margins the same as the spacing between them.
Stack view: In a permutation of the prior point, in iOS 9, you can also use UIStackView, designed precisely for evenly spacing views. In this case, put two buttons each in three horizontal stack views, and then place those stack views within a vertical stack view. This achieves six evenly sized container views.
See WWDC 2015 video What's New in Cocoa Touch.
The problem with stack views is that they can be used to ensure even spacing between the arranged subviews, they don't ensure spacing before the first arranged view nor after the last arranged view. So, the kludge to get around that is to, for horizontal stack view, include two more zero width views (or zero height for vertical stack views). Then when you use even spacing on the stack view, it also give you what will appear to be spacing before and after all of the arranged subviews.
NSLayoutAttributeCenterX with multiple: Another technique involves defining the attribute:NSLayoutAttributeCenterX and attribute:NSLayoutAttributeCenterY attributes for your six buttons, but rather than using the constant values, use the multiplier field. This technique enjoys a little simplicity, but doesn't always render the desired effect, so I won't describe it unless it's something you definitely want to pursue. I've already entered tl:dr territory here.
Collection view: Another approach is to use a UICollectionView, which handles this scenario gracefully. It's well designed to let you layout cells in a grid.
Hardcoding values: For the sake of completeness, I'll note that you could simply specify specific values for A, B, C, and D (as well as the width and height constraints). You don't even have to worry about setting the E constraints, but rather just set the vertical center constraint of the middle two to their superview, and you're effectively done (because the spacing represented by E should be a natural result of the previous steps, assuming A=C and B=D). If you want to adjust these values on the basis of device size and/or orientation, you can then implement a viewWillLayoutSubviews to adjust the constants for these constraints according to the size of the view.
Update: I have a better solution that does not use spacers. Check it out here.
Ok, this can be achieved very quickly in IB. It's so so simple. Here's a diagram that will help illustrate.
Assume v1-6 are your buttons, and s1-5 are your spacers.
1) in IB control drag out all of the connections shown by the red lines.
2) shift click v1-6 and pin icon (looks like |-I-| ) set the width and height to a definite value. also, set the height and width to be equal.
3) shift select s1-4 (not 5) and set the height to equal. do not give it a definite height, since this should be calculated by the system. you might also need to set the widths of s1-4 to be equal, but don't give them a definite width.
4) control drag from the centre views to the leading and trailing edge and set the centre constraint.
So, you might think, ok, this should work now. It doesn't. Here's my app running in portrait with slightly different colors. Looks good. (Notice, you would make the spacers invisible once you get it setup).
But when I rotate, oops!
What's happening here? The problem is incredibly easy to solve once we understand what's gone wrong. What we want is for IB to not shrink our views. We want IB to make the spacers and the spaces to shrink and grow as necessary, but to leave our views alone. Basically, IB has shrunk the spacers down as far as it can in portrait and to attempt to make everything fit IB has shrunk our views. But we wanted IB to shrink the vertical spaces between views and spacers, not our views. The solution is so easy. All we have to do is adjust the priority of the vertical spaces and all is well. So, select the vertical spaces in IB and adjust the priority to 750. The vertical spacing lines will show as dashed. Done.
Ok, so here's everything as we expect it.
And with the spacers made clear:

Invoice / OCR: Detect two important points in invoice image

I am currently working on OCR software and my idea is to use templates to try to recognize data inside invoices.
However scanned invoices can have several 'flaws' with them:
Not all invoices, based on a single template, are correctly aligned under the scanner.
People can write on invoices
etc.
Example of invoice: (Have to google it, sadly cannot add a more concrete version as client data is confidential obviously)
I find my data in the invoices based on the x-values of the text.
However I need to know the scale of the invoice and the offset from left/right, before I can do any real calculations with all data that I have retrieved.
What have I tried so far?
1) Making the image monochrome and use the left and right bounds of the first appearance of a black pixel. This fails due to the fact that people can write on invoices.
2) Divide the invoice up in vertical sections, use the sections that have the highest amount of black pixels. Fails due to the fact that the distribution is not always uniform amongst similar templates.
I could really use your help on (1) how to identify important points in invoices and (2) on what I should focus as the important points.
I hope the question is clear enough as it is quite hard to explain.
Detecting rotation
I would suggest you start by detecting straight lines.
Look (perhaps randomly) for small areas with high contrast, i.e. mostly white but a fair amount of very black pixels as well. Then try to fit a line to these black pixels, e.g. using least squares method. Drop the outliers, and fit another line to the remaining points. Iterate this as required. Evaluate how good that fit is, i.e. how many of the pixels in the observed area are really close to the line, and how far that line extends beyond the observed area. Do this process for a number of regions, and you should get a weighted list of lines.
For each line, you can compute the direction of the line itself and the direction orthogonal to that. One of these numbers can be chosen from an interval [0°, 90°), the other will be 90° plus that value, so storing one is enough. Take all these directions, and find one angle which best matches all of them. You can do that using a sliding window of e.g. 5°: slide accross that (cyclic) region and find a value where the maximal number of lines are within the window, then compute the average or median of the angles within that window. All of this computation can be done taking the weights of the lines into account.
Once you have found the direction of lines, you can rotate your image so that the lines are perfectly aligned to the coordinate axes.
Detecting translation
Assuming the image wasn't scaled at any point, you can then try to use a FFT-based correlation of the image to match it to the template. Convert both images to gray, pad them with zeros till the originals take up at most 1/2 the edge length of the padded image, which preferrably should be a power of two. FFT both images in both directions, multiply them element-wise and iFFT back. The resulting image will encode how much the two images would agree for a given shift relative to one another. Simply find the maximum, and you know how to make them match.
Added text will cause no problems at all. This method will work best for large areas, like the company logo and gray background boxes. Thin lines will provide a poorer match, so in those cases you might have to blur the picture before doing the correlation, to broaden the features. You don't have to use the blurred image for further processing; once you know the offset you can return to the rotated but unblurred version.
Now you know both rotation and translation, and assumed no scaling or shearing, so you know exactly which portion of the template corresponds to which portion of the scan. Proceed.
If rotation is solved already, I'd just sum up all pixel color values horizontally and vertically to a single horizontal / vertical "line". This should provide clear spikes where you have horizontal and vertical lines in the form.
p.s. Generated a corresponding horizontal image with Gimp's scaling capabilities, attached below (it's a bit hard to see because it's only one pixel high and may get scaled down because it's > 700 px wide; the url is http://i.stack.imgur.com/Zy8zO.png ).

Algorithms for placing images on a screen "nicely"

Note: This is not for a webpage, it is a simple program that holds a set of images and will randomly pick a number of images and display them on the screen. Imagine working with an image editor and manually positioning imported images on the canvas.
I am having difficulty coming up with a way to position a set of arbitrary images on a screen of fixed dimension (it's just a window)
So for example, if I have one image, I would probably just position it in the center of the screen.
|
If I have two images, I would try to place them in the center of the screen, but then spread them apart horizontally so that they look centered relative to each other and also the screen.
| |
But what if one image is larger than the other two? I might have something like
|-----|
| |
Similarly, maybe I have two larger ones and two smaller ones
|-----| |-----|
| |
So that the large one appears "in the back" while the small ones are up front.
It is inevitable that some images will end up covering up parts of other images but the best I can do is try to make it as orderly as possible.
I can quickly grab the dimensions of each image object that is to be drawn, and there is a limit on how many images will be drawn (from 1 to 8 inclusive).
Images can be drawn anywhere on the screen, and if any part of the image is outside of the screen those parts will just be cut off. All images have dimensions smaller than the dimensions of the screen, and are typically no bigger than 1/4 of the entire screen.
What is a good way to approach this problem? Even handling the base cases like having two images (of possibly different sizes) is already pretty confusing.
You could treat this as the 2D bin packing problem, which will optimise for non-overlapping rectangles in a "compact" way, though aesthetics won't be a consideration.
If you want to roll your own, you could try placing all images on the canvas on a grid, with the centre-to-centre spacing being large enough that no images overlap. Then "squash" the images closer together, left to right and top to bottom, to reduce the amount of whitespace.
html tables of 100% width and height (with disabled overflows) are a good starting point IMO - in the first iteration just order the pictures by size and make 8 templates like:
<tr><td><img></td></tr>
<tr><td><img></td><td><img></td></tr>
2 rows, first with colspan=2
...
then find some ugly cases and make special rules for them (like for 3 vertical images make 1 row, ...)

Resources