c# - DrawImage fails to position sliced images correctly -


for couple of days i've tried figure out why nine-slice code not work expected. far can see, there seems issue graphics.drawimage method handles 9 slice images incorrectly. problem how compensate incorrect scaling performed when running code on compact framework. might add code of course works when running in full framework environment. problem occurs when scaling image larger image not other way around. here snippet:

public class nineslicebitmapsnippet {     private bitmap m_originalbitmap;      public int cornerlength { get; set; }      /// <summary>     /// initializes new instance of nineslicebitmapsnippet class.     /// </summary>     public nineslicebitmapsnippet(bitmap bitmap)     {         cornerlength = 5;         m_originalbitmap = bitmap;     }      public bitmap scalesinglebitmap(size size)     {         bitmap scaledbitmap = new bitmap(size.width, size.height);         int[] horizontaltargetslices = slice(size.width);         int[] verticaltargetslices = slice(size.height);          int[] horizontalsourceslices = slice(m_originalbitmap.width);         int[] verticalsourceslices = slice(m_originalbitmap.height);          using (graphics graphics = graphics.fromimage(scaledbitmap))         {             using (brush brush = new solidbrush(color.fuchsia))             {                 graphics.fillrectangle(brush, new rectangle(0, 0, size.width, size.height));             }              int horizontaltargetoffset = 0;             int verticaltargetoffset = 0;              int horizontalsourceoffset = 0;             int verticalsourceoffset = 0;              (int x = 0; x < horizontaltargetslices.length; x++)             {                 verticaltargetoffset = 0;                 verticalsourceoffset = 0;                 (int y = 0; y < verticaltargetslices.length; y++)                 {                     rectangle destination = new rectangle(horizontaltargetoffset, verticaltargetoffset, horizontaltargetslices[x], verticaltargetslices[y]);                     rectangle source = new rectangle(horizontalsourceoffset, verticalsourceoffset, horizontalsourceslices[x], verticalsourceslices[y]);                      graphics.drawimage(m_originalbitmap, destination, source, graphicsunit.pixel);                      verticaltargetoffset += verticaltargetslices[y];                     verticalsourceoffset += verticalsourceslices[y];                 }                  horizontaltargetoffset += horizontaltargetslices[x];                 horizontalsourceoffset += horizontalsourceslices[x];             }         }         return scaledbitmap;     }      public int[] slice(int length)     {         int cornerlength = cornerlength;          if (length <= (cornerlength * 2))             throw new exception("image small sliceing up");          int[] slices = new int[3];         slices[0] = cornerlength;         slices[1] = length - (2 * cornerlength);         slices[2] = cornerlength;          return slices;     } } 

so, question is, how compensate incorrect scaling?

/dan

after more trial , error i've found solution problem. scaling problems has been top-center, right-center, bottom-center , left-center slices since they're stretched in 1 direction according logic of 9 slice scaling. if apply temporarely square stretch slices before applying correct stretch final bitmap correct. once again problem visible in .net compact framework of windows ce device (smart device). here's snippet code adjusting bug in cf. concern slices square stretched take more memory due correction code. on other hand step short period of time might away it. ;)

    public class nineslicebitmapsnippet {     private bitmap m_originalbitmap;      public int cornerlength { get; set; }      public nineslicebitmapsnippet(bitmap bitmap)     {         cornerlength = 5;         m_originalbitmap = bitmap;     }      public bitmap scale(size size)     {         if (m_originalbitmap != null)         {             return scalesinglebitmap(size);         }          return null;     }      public bitmap scalesinglebitmap(size size)     {         bitmap scaledbitmap = new bitmap(size.width, size.height);         int[] horizontaltargetslices = slice(size.width);         int[] verticaltargetslices = slice(size.height);          int[] horizontalsourceslices = slice(m_originalbitmap.width);         int[] verticalsourceslices = slice(m_originalbitmap.height);          using (graphics graphics = graphics.fromimage(scaledbitmap))         {             using (brush brush = new solidbrush(color.fuchsia))             {                 graphics.fillrectangle(brush, new rectangle(0, 0, size.width, size.height));             }              int horizontaltargetoffset = 0;             int verticaltargetoffset = 0;              int horizontalsourceoffset = 0;             int verticalsourceoffset = 0;              (int x = 0; x < horizontaltargetslices.length; x++)             {                 verticaltargetoffset = 0;                 verticalsourceoffset = 0;                 (int y = 0; y < verticaltargetslices.length; y++)                 {                     rectangle destination = new rectangle(horizontaltargetoffset, verticaltargetoffset, horizontaltargetslices[x], verticaltargetslices[y]);                     rectangle source = new rectangle(horizontalsourceoffset, verticalsourceoffset, horizontalsourceslices[x], verticalsourceslices[y]);                      bool iswidthaffectedbyverticalstretch = (y == 1 && (x == 0 || x == 2) && destination.height > source.height);                     bool isheightaffectedbyhorizontalstretch = (x == 1 && (y == 0 || y == 2) && destination.width > source.width);                     if (isheightaffectedbyhorizontalstretch)                     {                         bypassdrawimageerror(graphics, destination, source, orientation.horizontal);                     }                     else if (iswidthaffectedbyverticalstretch)                     {                         bypassdrawimageerror(graphics, destination, source, orientation.vertical);                     }                     else                     {                         graphics.drawimage(m_originalbitmap, destination, source, graphicsunit.pixel);                     }                      verticaltargetoffset += verticaltargetslices[y];                     verticalsourceoffset += verticalsourceslices[y];                 }                  horizontaltargetoffset += horizontaltargetslices[x];                 horizontalsourceoffset += horizontalsourceslices[x];             }         }         return scaledbitmap;     }      private void bypassdrawimageerror(graphics graphics, rectangle destination, rectangle source, orientation orientationadjustment)     {         size adjustedsize = size.empty;         switch (orientationadjustment)         {             case orientation.horizontal:                 adjustedsize = new size(destination.width, destination.width);                 break;             case orientation.vertical:                 adjustedsize = new size(destination.height, destination.height);                 break;             default:                 break;         }          using (bitmap quadscaledbitmap = new bitmap(adjustedsize.width, adjustedsize.height))         {             using (graphics tempgraphics = graphics.fromimage(quadscaledbitmap))             {                 tempgraphics.clear(color.fuchsia);                 tempgraphics.drawimage(m_originalbitmap, new rectangle(0, 0, adjustedsize.width, adjustedsize.height), source, graphicsunit.pixel);             }             graphics.drawimage(quadscaledbitmap, destination, new rectangle(0, 0, quadscaledbitmap.width, quadscaledbitmap.height), graphicsunit.pixel);         }     }      public int[] slice(int length)     {         int cornerlength = cornerlength;          if (length <= (cornerlength * 2))             throw new exception("image small sliceing up");          int[] slices = new int[3];         slices[0] = cornerlength;         slices[1] = length - (2 * cornerlength);         slices[2] = cornerlength;          return slices;     } } 

Comments

Popular posts from this blog

linux - Using a Cron Job to check if my mod_wsgi / apache server is running and restart -

actionscript 3 - TweenLite does not work with object -

jQuery Ajax Render Fragments OR Whole Page -