c# - How to update PictureBox from BackgroundThread? -
i'm doing expensive calculations in background thread , need able assign picturebox1.image after each cycle of calculations. use using delegates, been long time , things don't seem work way anymore.
i tried putting assignment in workercompleted event handler, can't figure out how restart backgroundworker1. i've been @ day , feel enormously frustrated, use easy do.
this relevant part of code:
using system; using system.globalization; using system.collections.generic; using system.drawing; using system.io; using system.windows.forms; using knowncolorspalette; namespace color_visualizer { public partial class form1 : form { static cultureinfo m_culture = cultureinfo.currentculture; double[,][] distances = new double[3000, 3000][]; fastpixel m_fp; public form1() { initializecomponent(); windowstate = formwindowstate.maximized; this.picturebox1.loadcompleted += new system.componentmodel.asynccompletedeventhandler(picturebox1_loadcompleted); coordinatesystem.assignme(this); } private void form1_load(object sender, eventargs e) { readcolors(); // reads text file alternating name , rgb hex of // wikipedia's 1200+ named colors. point3d p = new point3d(127.5, 127.5, 127.5); foreach (foundcolors fc in m_lcolors.values) fc.pt = fc.color - p; coord = new coordinatesystem(new plane(new point3d(-127.5, -127.5, -127.5), new point3d(-1, 0, 0))); backgroundworker1.runworkerasync(); } double fspeed = 5; point3d m_pnormal = new point3d(); private void backgroundworker1_dowork(object sender, system.componentmodel.doworkeventargs e) { double fangle, fradius, d; point3d vu, vv; point plocation = new point(); m_pnormal = coord.plane.normal; fangle = math.atan2(m_pnormal.y, m_pnormal.x); fradius = math.sqrt(m_pnormal.x * m_pnormal.x + m_pnormal.y * m_pnormal.y); fangle += fspeed * 180 / math.pi; m_pnormal.x = math.cos(fangle) * fradius; m_pnormal.y = math.sin(fangle) * fradius; m_fp.lock(); m_fp.clear(color.black); foreach (foundcolors fc in m_lcolors.values) { vu = new point3d(coord.u); d = dist(fc.pt, ref vu); vv = coord.v; vv.mult(d); plocation.x = (int)(m_midhoriz + vu.norm()); plocation.y = (int)(m_midvert + vv.norm()); m_fp.setpixel(plocation, fc.color); } m_fp.unlock(); } double m_fdist, m_fdot; public double dist(point3d pt, ref point3d vu) { double c1 = pt.dot(vu); double c2 = vu.dot(vu); double b = c1 / c2; vu.mult(b); m_fdot = pt.dot(coord.normal); m_fdist = pt.norm(pt - vu); return m_fdist; } double m_midhoriz, m_midvert; private void backgroundworker1_runworkercompleted(object sender, system.componentmodel.runworkercompletedeventargs e) { picturebox1.image = m_fp.bitmap; } private void form1_resize(object sender, eventargs e) { m_midhoriz = picturebox1.width / 2; m_midvert = picturebox1.height / 2; m_fp = new fastpixel(new bitmap(picturebox1.width, picturebox1.height)); } } }
and part of support code:
using system; using system.drawing; using system.diagnostics; using system.windows.forms; namespace color_visualizer { public partial class form1 : form { class coordinatesystem { const int max = 256; const double planewidth = 600; static form1 me; static point3d axisz = new point3d(0, 0, 1); static point3d axisy = new point3d(0, 1, 0); private plane m_plane = new plane(new point3d(128, 128, 128), new point3d(-128, 0, 0)); private point3d m_pv = new point3d(0, 0, 0); private point3d m_pu = new point3d(0, 0, 0); private double m_finc; public coordinatesystem(plane axaxis) { m_finc = planewidth / me.clientsize.height; plane = axaxis; } public static void assignme(form1 form) { me = form; } public point3d u { { return m_pu; } protected set { m_pu = value; } } public point3d v { { return m_pv; } protected set { m_pv = value; } } public point3d normal { { return m_plane.normal; } set { m_plane.normal = value; } } static double coserror = 0.99619469809174553229501040247389; public plane plane { { return m_plane; } set { m_plane = value; if (m_plane.dot(axisz) > coserror) u = u.cross(m_plane, axisy); else u = u.cross(m_plane, axisz); u.div(u.norm()); v = u.cross(u, m_plane); v.div(v.norm()); } } } [debuggerdisplayattribute("x = {x}, y = {y}, z = {z}")] public class point3d { public double x, y, z; public point3d(double _x, double _y, double _z) { x = _x; y = _y; z = _z; } public point3d(point3d p) { x = p.x; y = p.y; z = p.z; } public point3d() { x = 0; y = 0; z = 0; } public bool equals(point3d p) { return x == p.x & y == p.y & z == p.z; } public override bool equals(object obj) { return equals((point3d)obj); } public static bool operator ==(point3d p1, point3d p2) { return p1.equals(p2); } public static bool operator !=(point3d p1, point3d p2) { return !p1.equals(p2); } public static point3d operator -(point3d e, point3d s) { return new point3d(e.x - s.x, e.y - s.y, e.z - s.z); } public static point3d operator +(point3d e, point3d s) { return new point3d(e.x + s.x, e.y + s.y, e.z + s.z); } public static point3d operator *(double m, point3d v) { return new point3d(m * v.x, m * v.y, m * v.z); } public static point3d operator *(point3d v, double m) { return new point3d(v.x / m, v.y / m, v.z / m); } public static point3d operator /(double m, point3d v) { return new point3d(m * v.x, m * v.y, m * v.z); } public static point3d operator /(point3d v, double m) { return new point3d(v.x / m, v.y / m, v.z / m); } public static implicit operator color(point3d p) { return color.fromargb((int)p.x, (int)p.y, (int)p.z); } public static implicit operator point3d(color c) { return new point3d(c.r, c.g, c.b); } //public override int gethashcode() //{ // unchecked // { // var hash = new spookyhash(); // hash.update(x); // hash.update(y); // hash.update(z); // return hash.final().gethashcode(); // } //} // dot product (3d) allows vector operations in arguments public double dot(point3d u, point3d v) { return u.x * v.x + u.y * v.y + u.z * v.z; } public double dot(point3d u) { return u.x * x + u.y * y + u.z * z; } public double norm(point3d v) { return math.sqrt(dot(v, v)); } // norm = length of vector public double norm() { return math.sqrt(dot(this, this)); } // norm = length of vector public double dist(point3d u, point3d v) { return norm(u - v); } // distance = norm of difference public double dist(point3d u) { return norm(this - u); } public point3d cross(point3d u, point3d v) { return new point3d(u.y * v.z - u.z * v.y, u.z * v.x - u.x * v.z, u.x * v.y - u.y * v.x); } public point3d cross(point3d u) { return new point3d(u.y * z - u.z * y, u.z * x - u.x * z, u.x * y - u.y * x); } public void add(point3d p) { x += p.x; y += p.y; z += p.z; } public void mult(double m) { x *= m; y *= m; z *= m; } public void div(double m) { x /= m; y /= m; z /= m; } } class plane : point3d { point3d m_pnormal; public plane(point3d porigin, point3d pnormal) : base(porigin) { m_pnormal = pnormal; } public plane(point3d p) : base(p) { } public plane(double x, double y, double z) : base(x, y, z) { } public point3d normal { { return m_pnormal; } set { m_pnormal = value; } } public double pointtoplane(point3d p) { return p.dot(normal); } } private coordinatesystem m_coordsys; private coordinatesystem coord { { return m_coordsys; } set { m_coordsys = value; } } } }
and more support code:
[debuggerdisplayattribute("{name}, r={color.r}, g={color.g}, b={color.b}")] class foundcolors { public color color = color.empty; public string name = ""; public cielab_color clab; public point3d pt; public list<int> lclosest = new list<int>(); public int nfarthest; public foundcolors(foundcolors fc) { color = fc.color; name = fc.name; clab = new cielab_color(fc.clab.cie_l, fc.clab.cie_a, fc.clab.cie_b); lclosest.addrange(fc.lclosest); nfarthest = fc.nfarthest; } public foundcolors() { } }
the invoke method work if thread.sleep() 200ms.
m_fp.unlock(); this.invoke((methodinvoker)delegate () { picturebox1.image = m_fp.bitmap; }); thread.sleep(200); } while (true);
haven't tested lower limit, won't consistent across machines, reporting won't informative.
Comments
Post a Comment