firstly want apologize program being half done, want try , fix problem before continue program.
the following in entire solution far:
using system; using system.collections.generic; using system.componentmodel; using system.data; using system.drawing; using system.linq; using system.text; using system.threading.tasks; using system.windows.forms; using system.threading; using system.drawing; namespace test { public partial class form1 : form { public form1() { initializecomponent(); } private void button1_click(object sender, eventargs e) { datetime dtstart = datetime.now; bitmap pic = new bitmap("test.jpg"); bitmap returnimg = new bitmap(pic.width, pic.height); graphics g = graphics.fromimage(pic); color clr; int[] argb = new int[4]; (int = 0; < pic.width; i++) // pic.width = 50 { (int k = 0; k < pic.height; k++) // pic.height = 50 { clr = pic.getpixel(i, k); argb[0] = clr.a; argb[1] = clr.r; argb[2] = clr.g; argb[3] = clr.b; new thread(() => { if (k < 50) { //here problem, integer k still gets value 50 assigned it. g.drawimage(new bitmap(getbestpic(argb)), new point(i, k)); } }).start(); } } returnimg = new bitmap(pic.width, pic.height, g); returnimg.save("createdimage.jpg"); } //get picture best suited replace pixel private string getbestpic(int[] argb) { int numofpics = 5; int[] currentbest = new int[2]; currentbest[0] = 255; currentbest[1] = 150; (int = 0; < numofpics; i++) { int compare = compareargb(getaveragergb(new bitmap((i + 1).tostring()+".jpg")), argb); if (compare < currentbest[0]) { currentbest[0] = compare; currentbest[1] = + 1; } } return currentbest[1].tostring() + ".jpg"; } // smaller value, closer camparison private int compareargb(int[] one, int[] two) { int [] tmp = new int[4]; tmp[0] = convert.toint32(math.abs(one[0] - two[0])); tmp[1] = convert.toint32(math.abs(one[1] - two[1])); tmp[2] = convert.toint32(math.abs(one[2] - two[2])); tmp[3] = convert.toint32(math.abs(one[3] - two[3])); return (tmp[0] + tmp[1] + tmp[2] + tmp[3]); } //return int arry size 4 contaning argb values private int[] getaveragergb(bitmap img) { color clr; int aplha = 0; int red = 0; int green = 0; int blue = 0; (int = 0; < img.width; i++) { (int k = 0; k < img.height; k++) { clr = img.getpixel(i, k); aplha += clr.a; red += clr.r; green += clr.g; blue += clr.b; } } aplha = aplha / (img.width * img.height); red = red / (img.width * img.height); green = green / (img.width * img.height); blue = blue / (img.width * img.height); int[] re = new int[] {aplha,red,green,blue}; return re; } } } this montage program creating. comparing each pixel rgb of main picture average rgb of list of thumbnails. thumbnail average rgb closes pixel rgb used replace pixel.
i know there going lot of criticism of program. know resolution of resulting picture going huge ens.
the issue want why integer k in button1_click function increasing value 50, when there check less 50 in thread , loop k should not go 50. issue not occur when take threading out , happens randomly. value of integer varies when program breaks (because k gets assigned value 50). why cannot use break point or step through program. because happen randomly, when there lot of threads created.
thanks on this.
the issue results fact c# closures capture variable itself, not value. combined scoping of for-loop variable prior c# 5.0 mean value of k seen code running on separate thread change loop on main thread iterates through values, , in case importantly, can change between if (k < 50) check , subsequent use of k. msdn describes changes in c# 5.0 here.
if catch @ right moment, value of k can increment 50 51 result of for-loop on final iteration after if (k < 50) check before if-statement body.
as result of same issue, you'll find values of k skipped, , processed multiple times different threads.
to resolve need assign k local variable , capture instead. since variable localk local iteration of loop, captured value not change within thread:
... var localk = k; new thread(() => { if (localk < 50) { g.drawimage(new bitmap(getbestpic(argb)), new point(i, localk)); } }).start(); ... it's worth adding it's practically guaranteed running in threaded manner drastically reduce performance overhead of creating , switching between 2500 threads far outweigh benefit might gained parallel processing.
Comments
Post a Comment