Windows Phone - quick blur effect use on bitmap image in background - c#

I have cover image for artist that I am using in center of page with 200x200 resolution. I want to repeat this image to background too but change it so user can recognize colors and some shapes that are big. I am not sure which name has this effect in english. I think something as blug, smoothing and something like that.
I found that this block of code do what I want:
coverBitmap.ImageOpened += (s, args) =>
{
var wb = new WriteableBitmap((BitmapImage)s);
var newHeight = 800;
wb = wb.Resize(newHeight, newHeight, WriteableBitmapExtensions.Interpolation.Bilinear);
wb = wb.Crop(new Rect(160, 0, 480, 800));
wb = wb.Convolute(WriteableBitmapExtensions.KernelGaussianBlur5x5);
var brush = new ImageBrush {ImageSource = wb};
LayoutRoot.Background = brush;
};
Problem is that with KernelGaussianBlur5x5 it's still too much sharp (precise). I create my own matrix for 19x19:
var array = new[,]
{
{16, 17, 19, 20, 21, 22, 23, 24, 24, 24, 24, 24, 23, 22, 21, 20, 19, 17, 16},
{17, 19, 20, 22, 23, 24, 25, 26, 26, 26, 26, 26, 25, 24, 23, 22, 20, 19, 17},
{19, 20, 22, 24, 25, 26, 27, 28, 28, 28, 28, 28, 27, 26, 25, 24, 22, 20, 19},
{20, 22, 24, 25, 27, 28, 29, 30, 30, 30, 30, 30, 29, 28, 27, 25, 24, 22, 20},
{21, 23, 25, 27, 28, 29, 31, 31, 32, 32, 32, 31, 31, 29, 28, 27, 25, 23, 21},
{22, 24, 26, 28, 29, 31, 32, 33, 33, 33, 33, 33, 32, 31, 29, 28, 26, 24, 22},
{23, 25, 27, 29, 31, 32, 33, 34, 34, 35, 34, 34, 33, 32, 31, 29, 27, 25, 23},
{24, 26, 28, 30, 31, 33, 34, 35, 35, 36, 35, 35, 34, 33, 31, 30, 28, 26, 24},
{24, 26, 28, 30, 32, 33, 34, 35, 36, 36, 36, 35, 34, 33, 32, 30, 28, 26, 24},
{24, 26, 28, 30, 32, 33, 35, 36, 36, 36, 36, 36, 35, 33, 32, 30, 28, 26, 24},
{24, 26, 28, 30, 32, 33, 34, 35, 36, 36, 36, 35, 34, 33, 32, 30, 28, 26, 24},
{24, 26, 28, 30, 31, 33, 34, 35, 35, 36, 35, 35, 34, 33, 31, 30, 28, 26, 24},
{23, 25, 27, 29, 31, 32, 33, 34, 34, 35, 34, 34, 33, 32, 31, 29, 27, 25, 23},
{22, 24, 26, 28, 29, 31, 32, 33, 33, 33, 33, 33, 32, 31, 29, 28, 26, 24, 22},
{21, 23, 25, 27, 28, 29, 31, 31, 32, 32, 32, 31, 31, 29, 28, 27, 25, 23, 21},
{20, 22, 24, 25, 27, 28, 29, 30, 30, 30, 30, 30, 29, 28, 27, 25, 24, 22, 20},
{19, 20, 22, 24, 25, 26, 27, 28, 28, 28, 28, 28, 27, 26, 25, 24, 22, 20, 19},
{17, 19, 20, 22, 23, 24, 25, 26, 26, 26, 26, 26, 25, 24, 23, 22, 20, 19, 17},
{16, 17, 19, 20, 21, 22, 23, 24, 24, 24, 24, 24, 23, 22, 21, 20, 19, 17, 16}
};
I am not sure if I created it right. I found example from Microsoft samples from WinForm app and it results double[,] so I multiply by 10000 a then save it to int[,]. But when I apply this to my code it takes several seconds to create new image and I still want it more blur.
So is there a way how can I fast resize (expand) and crop image and then blur (smudge, smooth) it? Thanks

Related

Getting a list of date ranges that occur between the ranges of two lists of date ranges

Given I have a list of KeyValuePair<DateTime,DateTime> (which represent date ranges available), and I have another list of same type (which represent date ranges not available), then I need to end up with a list of date ranges that are within the first list's ranges, but with ranges in first list being sliced by ranges in the second list. It may be that second list only has one entry, but it covers the entire available range, in which case the result should be empty.
To illustrate:
available: |~| |~~~~| |~~| |~~~~~~~~~~~~~~~~~~~~~|
unavailab: |~~~~~~~~~| |~| |~~~~~~| |~~~~~~~~|
expected : |~| |~| |~~~~~~~| |~~|
Or, in code, if you prefer (not same as illustration):
IList<KeyValuePair<DateTime, DateTime>> scheduleDates = new List<KeyValuePair<DateTime, DateTime>>()
{
new KeyValuePair<DateTime, DateTime>(new DateTime(2016, 11, 15, 9, 0, 0), new DateTime(2016, 11, 15, 12, 0, 0)),
new KeyValuePair<DateTime, DateTime>(new DateTime(2016, 11, 15, 15, 0, 0), new DateTime(2016, 11, 15, 21, 0, 0))
};
IList<KeyValuePair<DateTime, DateTime>> holidayDates = new List<KeyValuePair<DateTime, DateTime>>()
{
new KeyValuePair<DateTime, DateTime>(new DateTime(2016, 11, 15, 11, 0, 0), new DateTime(2016, 11, 15, 16, 0, 0)),
new KeyValuePair<DateTime, DateTime>(new DateTime(2016, 11, 15, 17, 0, 0), new DateTime(2016, 11, 15, 18, 0, 0)),
new KeyValuePair<DateTime, DateTime>(new DateTime(2016, 11, 15, 20, 0, 0), new DateTime(2016, 11, 15, 24, 0, 0)),
};
IList<KeyValuePair<DateTime, DateTime>> availability = new List<KeyValuePair<DateTime, DateTime>>()
{
new KeyValuePair<DateTime, DateTime>(new DateTime(2016, 11, 15, 9, 0, 0), new DateTime(2016, 11, 15, 11, 0, 0)),
new KeyValuePair<DateTime, DateTime>(new DateTime(2016, 11, 15, 16, 0, 0), new DateTime(2016, 11, 15, 17, 0, 0)),
new KeyValuePair<DateTime, DateTime>(new DateTime(2016, 11, 15, 18, 0, 0), new DateTime(2016, 11, 15, 20, 0, 0))
};
What would be the most efficient method of doing this? I can only think of a brute force, and surely that's not the way to go. Note that both input lists and/or the output list could be empty.

How to assign a variable using 3 arrays in C#

I am trying to write an add-in for a finite element geology piece of software.
I have three arrays which are essentially a coordinate system. I want to assign a value to a variable depending on its position in the grid system. Basically I want to say if my node is within an x range and a y range, then my aquifer thickness at this node is this value. So far I have this.
//create an array of xcoords of data points:
double[] xcoord = new double[11] {0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50};
//create an array of ycoords of data points:
double[] ycoord = new double[11] {0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50};
//create an array of aquifer thickness
double[] aquiferThicknessPoints = new double[121]
{
10, 10, 12, 13, 12, 15, 14, 15, 14, 13, 13,
10, 10, 13, 15, 16, 14, 13, 15, 16, 12, 13,
12, 14, 15, 18, 19, 17, 14, 15, 18, 14, 14,
13, 14, 15, 18, 20, 17, 15, 17, 18, 15, 15,
14, 15, 17, 18, 21, 17, 18, 18, 19, 17, 16,
15, 15, 17, 17, 20, 21, 21, 19, 19, 18, 18,
15, 15, 17, 20, 20, 21, 22, 21, 19, 19, 19,
16, 17, 19, 20, 22, 23, 22, 21, 20, 20, 20,
17, 18, 20, 22, 23, 24, 24, 23, 22, 20, 21,
18, 19, 21, 22, 24, 25, 24, 23, 22, 22, 22,
19, 19, 22, 22, 24, 25, 25, 23, 23, 22, 23,
};
dataPointSpacingHalf = dataPointSpacing / 2;
for (int i = 0; i < xcoord.Length; i++)
{
for (int j = 0; j < ycoord.Length; j++)
{
if (nodeX >= (xcoord[i] - dataPointSpacingHalf) && (nodeX < (xcoord[i] + dataPointSpacingHalf)) && (nodeY >= (ycoord[j] - dataPointSpacingHalf) && (nodeY < (ycoord[j] + dataPointSpacingHalf))))
{
aquiferThickness = aquiferThicknessPoints[?];
}
}
}
I can see how the nested for loops will loop through 110 times, but i don't know how to assign my aquifer thickness from my array to each loop.
I open to any way of solving this problem as I'm very new new to programming and am still not sure which is the best way to achieve things.
Just use i * xcoord.Length + j insted of ?
Here is the code:
for (int i = 0; i < xcoord.Length; i++)
{
for (int j = 0; j < ycoord.Length; j++)
{
//Here is the magic!
//without considering coordinates
//aquiferThickness[i, j] = aquiferThicknessPoints[i * xcoord.Length + j];
//considering coordinates
aquiferThickness[i, j] =
aquiferThicknessPoints[
CoordToIndex(xNode,indexedCoords) * xcoord.Length +
CoordToIndex(yNode,indexedCoords)];
}
}
Also to consider the xNode, yNode coordinate, you can take this approach
Dictionary<int, double> indexedCoords = new Dictionary<int, double> { { 0, 0 }, { 1, 5 }, { 2, 10 }, .... };
int CoordToIndex(double node, Dictionary<int, double> indexedCoords)
{
return indexedCoords.First(i => i.Value > node).Key;
}
You want to use a two-dimensional array for your aquiferThicknessPoints:
double[,] aquiferThicknessPoints = new double[,]
{
{10, 10, 12, 13, 12, 15, 14, 15, 14, 13, 13},
{10, 10, 13, 15, 16, 14, 13, 15, 16, 12, 13},
{12, 14, 15, 18, 19, 17, 14, 15, 18, 14, 14},
{13, 14, 15, 18, 20, 17, 15, 17, 18, 15, 15},
// the rest
};
You can then address the data using the two coordinates:
aquiferThickness = aquiferThicknessPoints[j, i];
(or i, j, it's not obvious how your data is organized)

Split a string into substrings at variable widths in C#

I have a string of fixed length that has to be split at variable positions along the string to yield the substrings.
30849162 AUF3063100-2022031Doe Deanne 2610194031482100720081007200820000000000G43Z4206372 10 8 98282000000000911140000 00000000K6358Z8643K638 D126 Z099 320930090308009251519 132093 100720080071 0000000000000000000000000000000000000000000000000000000000000000000000002022031 000000000000000000000000000000000000000000000 00000000
The column break points are:
15, 18, 33, 61, 81, 89, 93, 94, 102, 110, 111, 114, 118,
Does anyone have an idea how I might do this? I have literally thousands of lines to parse
Put the break points in an array and use .substring() in a loop through those numbers. This is roughly how you want to do it, though you will have to adjust it to compensate for exactly where you want your column breaks.
int[] nums = {0, 15, 18, 33, 61, 81, 89, 93, 94, 102, 110, 111, 114, 118 };
string input = "Long string here";
for (int i = 0; i < nums.Length - 1; i++)
{
Console.WriteLine(input.Substring(nums[i], nums[i + 1] - nums[i]));
}
Or you could use some nasty LINQ like so..
public string[] ReturnMyStrings(string str)
{
int[] br = { 15, 18, 33, 61, 81, 89, 93, 94, 102, 110, 111, 114, 118 };
return br.Select((x, i) =>
str.Substring(br.ElementAtOrDefault(i - 1), x - br.ElementAtOrDefault(i - 1)))
.ToArray();
}
If you wanted to make your code scaleable you could implement some classes to do this work.
static void Main(string[] args)
{
string inputString = "30849162 AUF3063100-2022031Doe Deanne " +
"2610194031482100720081007200820000000000G43Z4" +
"206372 10 8 98282000000000911140000 00000000K" +
"6358Z8643K638 D126 Z099 320930090308009251519" +
"132093 100720080071 0000000000000000000000000" +
"000000000000000000000000000000000000000000000" +
"002022031 00000000000000000000000000000000000" +
"0000000000 00000000";
//myRecord will hold the entire input in its split form
var myRecord = new StringSplitterRecord()
{
fields = new List<StringSplitterField>()
{
//define all the different fields
new StringSplitterField(inputString, 0, 15, "Name of field 1"),
new StringSplitterField(inputString, 15, 3, "Name of field 2"),
new StringSplitterField(inputString, 18, 15, "Name of field 3"),
new StringSplitterField(inputString, 33, 28, "Name of field 4"),
new StringSplitterField(inputString, 61, 20, "Name of field 5"),
new StringSplitterField(inputString, 81, 8, "Name of field 6"),
new StringSplitterField(inputString, 93, 1, "Name of field 7"),
new StringSplitterField(inputString, 94, 8, "Name of field 8"),
new StringSplitterField(inputString, 102, 8, "Name of field 9"),
new StringSplitterField(inputString, 110, 1, "Name of field 10"),
new StringSplitterField(inputString, 111, 3, "Name of field 11"),
new StringSplitterField(inputString, 114, 4, "Name of field 12"),
}
};
}
class StringSplitterRecord
{
public List<StringSplitterField> fields;
}
class StringSplitterField
{
private string _contents;
private string _fieldType;
public StringSplitterField(string originalString, int startLocation, int length, string fieldType)
{
_contents = originalString.Substring(startLocation, length);
_fieldType = fieldType;
}
}
This will not only split your input string into the require pieces but it will put them all in a list with a name for each sub section. Then you can use LINQ etc to retrieve the data that you need.

Get a specific value from a specific array when having two dropdown lists

I have 5 arrays which represents 1 city each. Each position in the array represents the distance to another city (all arrays shares the same position for each specific city). And I have two dropdown lists from where the user is supposed to select two cities to calculate the distance between them.
It's set up like this:
// City0, City1, City2, City3, City4
int[] distanceFromCity0 = { 0, 16, 39, 9, 24 };
int[] distanceFromCity1 = { 16, 0, 36, 32, 54 };
int[] distanceFromCity2 = { 39, 36, 0, 37, 55 };
int[] distanceFromCity3 = { 9, 32, 37, 0, 21 };
int[] distanceFromCity4 = { 24, 54, 55, 21, 0 };
int cityOne = Convert.ToInt16(DropDownList1.SelectedValue);
int cityTwo = Convert.ToInt16(DropDownList2.SelectedValue);
And within the dropdown lists each city has the corresponding ID (city0 = 0, city1 = 1 etc)
I have tried a few different ways, but none of them really works.
So basically, how do I "connect" DropDownList1 to one of the arrays depending on the choice, and then connecting DropDownList2 to one of the positions in the selected array (from DropDownList1 selection) and print it out to Label1?
Is it easier with a 2D array?
This probably looks easy for you, but I'm a noob in C#.
One way would be to combine distanceFromCity0 ... distanceFromCity4 into a single 2D array and use the two cities as indexes to the distance value:
int[][] distanceBetweenCities = {
new[]{ 0, 16, 39, 9, 24 },
new[]{ 16, 0, 36, 32, 54 },
new[]{ 39, 36, 0, 37, 55 },
new[]{ 9, 32, 37, 0, 21 },
new[]{ 24, 54, 55, 21, 0 }
};
int cityOne = Convert.ToInt32(DropDownList1.SelectedValue);
int cityTwo = Convert.ToInt32(DropDownList2.SelectedValue);
var distance = distanceBetweenCities[cityOne][cityTwo];
Yes, using two-dimensional array is very easy. You can regard it like a matrix. Some code like below:
int[,] distanceMatrix = new int[5, 5] { { 0, 16, 39, 9, 24 },
{ 16, 0, 36, 32, 54 },
{ 39, 36, 0, 37, 55 },
{ 9, 32, 37, 0, 21 },
{ 24, 54, 55, 21, 0 }
};
int cityOne = Convert.ToInt32(DropDownList1.SelectedValue);
int cityTwo = Convert.ToInt32(DropDownList2.SelectedValue);
var distance = distanceMatrix[cityOne, cityTwo]; //the distance between cityOne and cityTwo;

Convert IObservable<byte[]> with irregular length byte arrays to IObservable<byte[]> with regular length arrays

I have an IObservable<byte[]> that gives me an uncertain amount of bytes in the byte array. I want to know how I go from that, to returning an IObservable<byte[]> with a set amount of bytes in each byte array. Let's assume we want 10 bytes at a time.
That is to say, if I get the following input if I were to subscribe:
{1, 2, 3, 4}
{5, 6}
{7, 8, 9}
{10}
{11, 12, 13, 14, 15}
{16}
{17, 18}
{19, 20}
Bytes.Subscribe(b => Console.WriteLine(b.Length));
The output would be
3
2
3
1
5
1
2
2
What I would like is to convert the input above into this:
{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
{11, 12, 13, 14, 15, 16, 17, 18, 19, 20}
Bytes.<WhateverItTakesToDoThat>.Subscribe(b => Console.WriteLine(b.Length));
The output would be
10
10
It must also work if an amount of bytes come in that are larger than a single output packet, i.e.:
{21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32}
{33, 34, 35, 36, 37, 38, 39, 40, 41}
{42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52}
Should be turned into
{21, 22, 23, 24, 25, 26, 27, 28, 29, 30}
{31, 32, 33, 34, 35, 36, 37, 38, 39, 40}
{41, 42, 43, 44, 45, 46, 47, 48, 49, 50}
(and be holding on to {51, 52}, waiting for more input to come along)
It's easy. Try this:
Bytes
.SelectMany(b => b)
.Buffer(10)
.Select(bs => bs.ToArray());
I came up with one solution after a bit of thinking and tinkering. The following code does what I want:
Bytes.Select( b => b.ToObservable() ) // Convert input to IObservable<IObservable<byte>>
.Merge( 1 ) // Merges the IObservable<IObservable<byte>> to an IObservable<byte>
// with the bytes in the right order
.Buffer( 4 ) // Wait until we have 4 bytes ready
.Select( bl => bl.ToArray() ) // Take these 4 bytes and turn them back into an array
.Subscribe( b => Console.WriteLine( b.Length ) );
This is probably inefficient, and I'm almost certain it's not he most efficient way of doing this, so if somebody out there can come up with a better, more efficient solution, I'm all ears!

Categories