Friday, August 24, 2018

How can I iterate through each pixel in a .gif image?

I need to step through a .gif image and determine the RGB value of each pixel, x and y coordinates. Can someone give me an overview of how I can accomplish this? (methodology, which namespaces to use, etc.)

Solved

This is a complete example with both methods, using LockBits() and GetPixel(). Besides the trust issues with LockBits() things can easily get hairy.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;

namespace BitmapReader
{
    class Program
    {
        static void Main(string[] args)
        {
            //Try a small pic to be able to compare output, 
            //a big one to compare performance
            System.Drawing.Bitmap b = new 
                System.Drawing.Bitmap(@"C:\Users\vinko\Pictures\Dibujo2.jpg"); 
            doSomethingWithBitmapSlow(b);
            doSomethingWithBitmapFast(b);
        }

        public static void doSomethingWithBitmapSlow(System.Drawing.Bitmap bmp)
        {
            for (int x = 0; x < bmp.Width; x++)
            {
                for (int y = 0; y < bmp.Height; y++)
                {
                    Color clr = bmp.GetPixel(x, y);
                    int red = clr.R;
                    int green = clr.G;
                    int blue = clr.B;
                    Console.WriteLine("Slow: " + red + " " 
                                       + green + " " + blue);
                }
            }
        }

        public static void doSomethingWithBitmapFast(System.Drawing.Bitmap bmp)
        {
            Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);

            System.Drawing.Imaging.BitmapData bmpData =
                bmp.LockBits(rect, 
                    System.Drawing.Imaging.ImageLockMode.ReadOnly,
                    bmp.PixelFormat);

            IntPtr ptr = bmpData.Scan0;

            int bytes = bmpData.Stride * bmp.Height;
            byte[] rgbValues = new byte[bytes];

            System.Runtime.InteropServices.Marshal.Copy(ptr, 
                           rgbValues, 0, bytes);

            byte red = 0;
            byte green = 0;
            byte blue = 0;

            for (int x = 0; x < bmp.Width; x++)
            {
                for (int y = 0; y < bmp.Height; y++)
                {
                    //See the link above for an explanation 
                    //of this calculation
                    int position = (y * bmpData.Stride) + (x * Image.GetPixelFormatSize(bmpData.PixelFormat)/8); 
                    blue = rgbValues[position];
                    green = rgbValues[position + 1];
                    red = rgbValues[position + 2];
                    Console.WriteLine("Fast: " + red + " " 
                                       + green + " " + blue);
                }
            }
            bmp.UnlockBits(bmpData);
        }
    }
}

You can load the image using new Bitmap(filename) and then use Bitmap.GetPixel repeatedly. This is very slow but simple. (See Vinko's answer for an example.)

If performance is important, you might want to use Bitmap.LockBits and unsafe code. Obviously this reduces the number of places you'd be able to use the solution (in terms of trust levels) and is generally more complex - but it can be a lot faster.


Monday, August 20, 2018

How to start a fragment Insted of opening new Activity, OnClick its opening new Activity, Is there any way I can open fragment

How to start a fragment Insted of opening new Activity, OnClick its opening new Activity, Is there any way I can open fragment.

@Override
protected void onPostExecute(List result) {
    super.onPostExecute(result);

  final MovieAdapter adapter = new MovieAdapter( getActivity().getApplicationContext(), R.layout.rownew, result );
        ////  getApplicationContext()   // getActivity is added by me
        lvMovies.setAdapter(adapter);

        //set data to list
        lvMovies.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView parent, View view, int position, long id) {
              //  Toast.makeText(getActivity().getBaseContext(),parent.getItemIdAtPosition(position)+" is selected",Toast.LENGTH_LONG).show();

                MovieModel movieModel = (MovieModel) adapter.getItem(position);

                Intent intent = new Intent("sanjay.apackage.torcente.com.torcentemotors.productdesc");
                intent.putExtra("productimage", movieModel.getProduct_image());
                //sanjay //
                intent.putExtra("productname",movieModel.getProduct_name());
                intent.putExtra("productprice", movieModel.getProduct_price());
                intent.putExtra("productcolor", movieModel.getProduct_color());
                intent.putExtra("originalprice", movieModel.getOriginal_price());
                intent.putExtra("appdesc", movieModel.getApp_desc());

                startActivity(intent);

                /*
                Fragment fragment_productdesc = new fragment_productdesc();
                FragmentTransaction transaction = getFragmentManager().beginTransaction();
                transaction.replace(R.id.main_container, fragment_productdesc ); // give your fragment container id in first parameter
                transaction.addToBackStack(null);  // if written, this transaction will be added to backstack
                transaction.commit();  */
            }
        });
    }

Solved

I think you want to send data from activity to fragment so please try this method to send data from your activity to method.

Create a custom fragment extending fragment put arguments and initialize.

public class MyFragment extends Fragment {
private View rootView;
private int type;

public MyFragment() {
    // Required empty public constructor
}

public static MyFragment newInstance(int type, Object object) {
    MyFragment fragment = new MyFragment();
    Bundle args = new Bundle();
    args.putInt("type", type);
    fragment.setArguments(args);
    return fragment;
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if (getArguments() != null) {
        type = getArguments().getInt(Key.TYPE);
    }
}

@Override
public View onCreateView(
        LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
        rootView = inflater.inflate(R.layout.fragment_slider, container,false);
    return rootView;
}

Sunday, August 19, 2018

How to pass a Bundle to Android Wear using MessageApi

I'm currently passing Bytes to AnroidWear using:

 MessageApi.SendMessageResult result = Wearable.MessageApi.sendMessage(
                        mGoogleApiClient, node.getId(), path, text.getBytes() ).await();

I want to send a proper Data Bundle to my Wearable, how do I do that?

Solved

Convert your bundle to bytes, and on receiver, convert bytes to Bundle.

With this simple method, you can send only String Bundle values.

(And, It seems that you can convert Bundle to String with GSON and BundleTypeAdapterFactory also, but I'm not tested.)

public void example() {
    // Value
    Bundle inBundle = new Bundle();
    inBundle.putString("key1", "value");
    inBundle.putInt("key2", 1); // will be failed
    inBundle.putFloat("key3", 0.5f); // will be failed
    inBundle.putString("key4", "this is key4");

    // From Bundle to bytes
    byte[] inBytes = bundleToBytes(inBundle);

    // From bytes to Bundle
    Bundle outBundle = jsonStringToBundle(new String(inBytes));

    // Check values
    String value1 = outBundle.getString("key1"); // good
    int value2 = outBundle.getInt("key2"); // fail
    float value3 = outBundle.getFloat("key3"); // fail
    String value4 = outBundle.getString("key4"); // good

}


private byte[] bundleToBytes(Bundle inBundle) {
    JSONObject json = new JSONObject();
    Set keys = inBundle.keySet();
    for (String key : keys) {
        try {
            json.put(key, inBundle.get(key));
        } catch (JSONException e) {
            //Handle exception here
        }
    }

    return json.toString().getBytes();
}


public static Bundle jsonStringToBundle(String jsonString) {
    try {
        JSONObject jsonObject = new JSONObject(jsonString);
        return jsonToBundle(jsonObject);
    } catch (JSONException ignored) {

    }
    return null;
}

public static Bundle jsonToBundle(JSONObject jsonObject) throws JSONException {
    Bundle bundle = new Bundle();
    Iterator iter = jsonObject.keys();
    while (iter.hasNext()) {
        String key = (String) iter.next();
        String value = jsonObject.getString(key);
        bundle.putString(key, value);
    }
    return bundle;
}

Friday, August 17, 2018

Replace character in url before routing in ASP.NET MVC

Can I manipulate the url before routing it, i.e. before MVC goes through my route configuration to find the route to use.

I'd like to replace some characters in the url, for example "www.test.com/ä/ö" to "www.test.com/a/o". That way, if a user typed those letter in the url, the right route would still be used.

Maybe there´s something that I can hook into to manipulate the url?

Edit: To clarify what I want I'll add an example. Let's say I have a routing configuration that looks like this: "{controller}/{action}". The user types www.test.com/MyCöntroller/MyÄction and I want to route that to the controller "MyController" and the action method "MyAction". I have to do the character replacement before the routing is done, otherwise no matching route will be found. Thus I'd like to replace all "ö" with "o" and all "ä" with "a" (and some more characters) BEFORE the routing is done. Is there any way to do this?

Edit2: After some research it seems like it is UrlRoutingModule that is the first to get the url in ASP.NET MVC. Maybe there is some way to hook into that?

Solved

Take a loot at this post, by creating custom route handler it is possible.

using System.Web.Routing; 
namespace My.Services
{
    public class MyRouteHander : IRouteHandler
    {
     ApplicationDbContext Db = new ApplicationDbContext();
     public IHttpHandler GetHttpHandler(RequestContext requestContext)
     {
         // Get route data values
         var routeData = requestContext.RouteData;
         var action = routeData.GetRequiredString("action");
         var controller = routeData.GetRequiredString("controller");

         //modify your action name here

             requestContext.RouteData.Values["action"] = actionName;
             requestContext.RouteData.Values["controller"] = "SpecialController";

         return new MvcHandler(requestContext);
     }
 }

}


Check out the answer to this question.

Basically you'll want to use the FilterAttribute with IActionFilter, and then apply the annotation to the ActionResult that services the route. This way you have an intermediary method to manipulate the URL before it's processed by your route configuration.