Using Map View to Display Location of Clicked Image in Phimpme

Previously in Phimpme Android app we used to display all the images on the map, based on their location they have taken. In the upcoming version, we are introducing mapview to specify the location when user checks out the details of the image. In this post, I am explaining that how I have implemented Google’s mapView in Phimpme. Note: The prerequisite to display image location in the map view, an image should have geolocation in its meta data. Let’s get started Step -1 : First, enable the setting to ‘Show mapview in Image description’ and save it somewhere. Although, it’s your choice you want to give users choice to view map or not. First, we need to turn on the movie visibility from map provider in settings. Right now we are adding two maps in our list Google maps and openstreetmap. Choose Map Provider from the list in Phimpme Once you choose your preference, it will get stored in sharedPref. As we are displaying the map in the image details so we need to add Image view of map. Step -2 : Add a ImageView in your XML, in which we will display map. <ImageView   android:id="@+id/photo_map"   android:layout_width="match_parent"   android:layout_height="150dp"   android:visibility="gone" /> Keep default visibility of mapview is GONE, If a user will enable map view in setting then we will make this image visible. Step -3 : Load image with map in ImageView: Good things are that StaticMapProvier gives you the URL of the image in corresponding to particular GeoLocation, which actually is a view of the map. Now we need to display mapview when the user taps on details of an image. ImageView imgMap = (ImageView) dialogLayout.findViewById(R.id.photo_map); final GeoLocation location; if ((location = f.getGeoLocation()) != null) {   PreferenceUtil SP = PreferenceUtil.getInstance(activity.getApplicationContext());   StaticMapProvider staticMapProvider = StaticMapProvider.fromValue(           SP.getInt(activity.getString(R.string.preference_map_provider), StaticMapProvider.GOOGLE_MAPS.getValue()));   Glide.with(activity.getApplicationContext())           .load(staticMapProvider.getUrl(location))           .asBitmap()           .centerCrop()           .animate(R.anim.fade_in)           .into(imgMap); To load an image, we used Glide Image library, you can use any library of your choice. MapView on the top of dialog box in Phimpme Step 4: Open navigation on the tap of mapView or Image. Attach a click listener on the imageView and on click of that create a Uri correspond to geolocation and through an Intent to Android to view that link, it will open Google maps with navigation. String uri = String.format(Locale.ENGLISH, "geo:%f,%f?z=%d", location.getLatitude(), location.getLongitude(), 17);           activity.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(uri))); Resources How to display map in static imageview : https://stackoverflow.com/questions/5324004/how-to-display-static-google-map-on-android-imageview Displaying location address : https://developer.android.com/training/location/display-address.html

Continue ReadingUsing Map View to Display Location of Clicked Image in Phimpme

Applying Filters on Images using Native Functions in Phimpme Android

In the Phimpme application, the user can apply multiple colorful filters on images captured from application’s camera or already available images on the device. This application of filters on images is performed using native image processing functions. We implemented many filters for enhancing the image. Implementation of few of the filter functions is shown below. Filters are applied to an image by modifying the color values of pixels in the Phimpme application. This is similar to the implementation of image enhancing functions in the editor of Phimpme. My post on that is available here. Black and White filter: Black and white filter can be called as gray scaling the image. In a gray scale image, there will only be a single color channel. If multiple channels are present, the corresponding pixel values in all channels will be same. Here in Phimpme, we have an RGB image. It has 3 color channels. Every pixel has three values. Black and white filter can be implemented by replacing those three different values with the average of those values. The implementation of the function and the resultant image with the comparison is shown below. void applyBlackAndWhiteFilter(Bitmap* bitmap) {  register unsigned int i;  unsigned int length = (*bitmap).width * (*bitmap).height;  register unsigned char grey;  unsigned char* red = (*bitmap).red;  unsigned char* green = (*bitmap).green;  unsigned char* blue = (*bitmap).blue;  for (i = length; i--;) {     grey = (red[i] + green[i] + blue[i]) / 3;     red[i] = truncate((int) grey);     green[i] = truncate((int) grey);     blue[i] = truncate((int) grey);  } }      Ansel Filter This Ansel Filter is a monotone filter present in Phimpme which is similar to black and white. Here in this filter, the contrast will be little high and gives the image artistic look. This is achieved in Phimpme by hard overlaying the gray pixel components of the image. The rest is same as the black and white filter. The implementation of hard overlay blending and the Ansel function is shown below with the resultant images. static unsigned char hardLightLayerPixelComponents(unsigned char maskComponent, unsigned char imageComponent) {  return (maskComponent > 128) ? 255 - (( (255 - (2 * (maskComponent-128)) ) * (255-imageComponent) )/256) : (2*maskComponent*imageComponent)/256; } void applyAnselFilter(Bitmap* bitmap) { /*initializations*/  unsigned char br,bg,bb;  for (i = length; i--; ) {       grey = (red[i] + green[i] + blue[i]) / 3;       int eff = hardLightLayerPixelComponents(grey, grey);       red[i] = truncate(eff);       green[i] = truncate(eff);       blue[i] = truncate(eff);  } }      Sepia Filter The Sepia Filter in Phimpme results in a monotone image with orangish yellow tone. Its implementation uses pre-defined look up tables(LUTs) for all the three channels. The luminosity of a particular pixel is found out and then the red, green, blue values are found out from the look up tables(LUTs) corresponding to that luminosity. The look up table arrays we used for the sepia effect in Phimpme are given below and the implementation is also shown below. const unsigned char sepiaRedLut[256] = {24, 24, 25, 26, 27, 28, 29, 30, 30, 30, 31, 32, 33,…

Continue ReadingApplying Filters on Images using Native Functions in Phimpme Android

Enhancing Images using Native functions in Phimpme Android

Enhancing the image can be performed by adjusting the brightness, contrast, saturation etc. of that image. In the Phimpme Android Image Application, we implemented many enhancement operations. All these image enhancement operations are performed by the native image processing functions. An image is made up of color channels. A gray-scale image has a single channel, colored opaque image has three channels and colored image with transparency has four channels. Each color channel of an image represents a two dimensional matrix of integer values. An image of resolution 1920x1080 has 1920 elements in its row and 1080 such rows. The integer values present in the matrices will be ranging from 0 to 255. For a grayscale image there will be a single channel. So, for that image, 0 corresponds to black color and 255 corresponds to white color. By changing the value present in the matrices, the image can be modified. The implementation of the enhancement functions in Phimpme Application are given below. Brightness Brightness adjustment is the easiest of the image processing functions in Phimpme. Brightness can be adjusted by increasing or decreasing the values of all elements in all color channel matrices. Its implementation is given below. void tuneBrightness(Bitmap* bitmap, int val) {  register unsigned int i;  unsigned int length = (*bitmap).width * (*bitmap).height;  unsigned char* red = (*bitmap).red;  unsigned char* green = (*bitmap).green;  unsigned char* blue = (*bitmap).blue;  signed char bright = (signed char)(((float)(val-50)/100)*127);  for (i = length; i--; ) {       red[i] =  truncate(red[i]+bright);       green[i] = truncate(green[i]+bright);       blue[i] = truncate(blue[i]+bright);  } }    low brightness, normal, high brightness(in the order) images are shown above For the above function, the argument val is given by the seekbar implemented in java activity. Its value ranges from 0 - 100, so a new variable is introduced to change the range of the input argument in the function. You can see that in the for loop there is function named truncate. As the name suggests it truncates the input argument’s value to accepted range. It is added to the top of the c file as below #define truncate(x) ((x > 255) ? 255 : (x < 0) ? 0 : x) Contrast Contrast of an image is adjusted in Phimpme application by increasing the brightness of the brighter pixel and decreasing value of the darker pixel. This is achieved by using the following formula for the adjustment contrast in editor of phimpme application. pixel[i] = {(259 x (C + 255))/(255 x (259 - C))} x (pixel[i] - 128) In the above formula, C is the contrast value and pixel[i] is the value of the element in the image matrix that we are modifying for changing the contrast.   low contrast, normal, high contrast(in the order) images are shown above So, after this formula for modifying every pixel value, the function looks like below void tuneContrast(Bitmap* bitmap, int val) {  register unsigned int i;  unsigned int length = (*bitmap).width * (*bitmap).height;  unsigned char* red = (*bitmap).red;  unsigned char* green = (*bitmap).green;  unsigned char*…

Continue ReadingEnhancing Images using Native functions in Phimpme Android

How to use Digital Ocean and Docker to setup Test CMS for Phimpme

One of the core feature of Phimpme app is sharing images to other different accounts, including various open source CMS such as Wordpress, Drupal etc and other open source data storage account such as OwnCloud, NextCloud etc. One can not have everything at place, but for development and testing purpose it is required in our end. So problem I was facing to get things done in most optimize way. I thought setting things on hosted server would be good, because it saves lots of time in setting locally in our system, adding all the dependencies. And also we cannot share the account as it is limited to our local environment. Digital Ocean caught my attention in providing hosting service. It is very easy to use with their droplet creation. Select as per your system requirement and service requirement, the droplet will be ready in few moments and we can use it anywhere. Note: DigitalOcean is a paid service. Student can use Github Education Pack for free credits on Digital Ocean. I used the same. I currently worked on Nextcloud integration so here in this blog I will tell how to quickly create nextcloud server using Digital Ocean and Docker. Step 1: Creating Droplet DigitalOcean completely work on droplets and one can anytime create and destroy different droplets associated with their account. Choose an Image So there are three options of choosing the image of Droplet. Distributions : Which is other operating systems you want to use One Click app: It is a very good feature as it creates everything for use in just one click. But again, it doesn’t provide everything, like there is no NextCloud. That’s why I used docker to take its image. Snapshots: This is if you saved your droplet already, so it will pick it and creates similar to the saved image. Here I selected Docker from one-click apps section. Selecting the size This is for selecting the size of the server we are creating, For small development purpose $5 plan is good. There is a good thing in DigitalOcean as it didn’t charge on the monthly basis to the use. It works on hourly basis and charge according to that. Also providing the SSD Disk for fast IO operations. Choose a datacenter Region Add SSH This is very important to add a ssh key. Otherwise you have to setup root password or used the shell they provide. To work on your computer terminal, its good that you setup an ssh key already and it to the account. How to get ssh key in your system: https://help.github.com/ Rename the number of droplet and name of the droplet and create. Now it will show there in your droplet section Step 2: Access the Server As we have already added the ssh key to our droplet. Now we can access it from our terminal. Open the terminal and type this ➜  ~ ssh root@<your IP> It will logged in to you root@docker-512mb-blr1-01:~# Our objective is setting a NextCloud Account.…

Continue ReadingHow to use Digital Ocean and Docker to setup Test CMS for Phimpme

Landing Page for Phimpme Android

Landing page for any app is very important for its distribution. Its provide all the relevant informations for the app, its download/ source link and screenshot of the app for preview of its view and features. As our Phimpme app is now reached to a milestone, so we decided to bring out a landing for it. Landing page is a simple static website which gives relevant informations and their links on a page. To develop a landing page, we can use multiple frameworks available for it. For example using Bootstrap, basic pages using html and css. As GitHub provides a free hosting service such as Github pages. I decided to work on jekyll which is easy to customize and hosted with GitHub pages. How I did in Phimpme Search for Open Source theme There are various open source themes present for jekyll, mainly you will get for blogs. I got this awesome app landing page. It fulfils our requirements of showing a screenshot, brief description and links. Create separate branch for Landing page The GitHub pages works from a separate branch. So I firstly created a orphan branch in main Phimpme Repository. And Clear the working directory. Orphan branches are those branch which do not have any commit history. It is highly required that branch should not have any commit history, because that will irrelevant for gh-pages branch. git checkout --orphan gh-pages git rm --cached -r . Test on Fork repo Now rebase your branch with the gh-pages branch created on the main repository. Add the complete jekyll code here. To reflect changes on github.io page. You need to enable that in settings. Enable gh-pages from settings Go to the Settings of your repo Scroll down to gh-pages section Here things are clear, as we need to select the source branch from where the gh-pages is hosted. We can directly choose some open source themes built over jekyll. Also there is a option to add custom domain, such phimp.me in our case. This all I’m writing as per the Developer perspective, where the developer have limited access to the repository and can’t access the settings of main repo. In that case push your code to by selecting the gh-pages base branch. Problems I faced The usual problem any Developer here faces is creating a orphan branch in main repo. This required removing all the files as well. Also to face less problem I recommend using some other editor such as Sublime Text, Atom etc. Or any other IDE other than Android Studio. Because in Android Studio after changing branch, it sync and rebuild again which actually takes lots of time. Resources GitHub Pages: https://pages.github.com/ GitHub Pages guide: https://guides.github.com/features/pages/ Create project pages using command line (Official): https://help.github.com/articles/creating-project-pages-using-the-command-line/ Adding a custom domain: https://help.github.com/articles/adding-or-removing-a-custom-domain-for-your-github-pages-site/  

Continue ReadingLanding Page for Phimpme Android

Phimpme: Merging several Android Projects into One Project

To speed up our development of the version 2 of the Phimpme Android app, we decided to use some existing Open Source libraries and projects such as Open Camera app for Camera features and Leafpic for the photo gallery. Integrating several big projects into one is a crucial step, and it is not difficult. Here are some points to ponder. Clone project separately. Build project and note down the features which you want to integrate. Explore the manifest file to know the Launcher, services and other permission app is taking. I explore the Leafpic app manifest file. Found out its Launcher class, and changed it with the our code. Looked at the permissions app required such as Camera, access fine location, write external storage. Follow Bottom Up approach while integrating. It makes life easier. By the bottom up approach I mean create a new branch and then start deleting the code which is not required. Always work in branch so that no code lost or messed up. Not everything is required at the moment. So I first integrate the whole leafpic app and then remove the splash screen. Also noted down the features needs to remove such as drawer, search bar etc. Remove and Commit, In a big project things are interlinked so removing one feature, actually made you remove most of the code. So my strategy is to focus on one feature and when it removed commit the code. This will help you in a reset hard your code anytime. Like a lot of times I use reset --hard in my code, because it messed up. Licensing: One thing which is most important in using open source code is their License. Always follow what is written in their License. This is the way we can give credit to their hard work. There are various types of licenses, three famous are Apache, MIT and GNU General Public License. All have their pros and cons. Apart of License there are some other condition as well. Like in leafpic which we are using in Phimpme has a condition to inform developers about the project in which we are using leafpic. Aware of File Duplication, sometimes many files have same name which results into file duplication. So refactor them already in the code. I refactor the MainActivity in leafpic to LFMainActivity to not to clash with the existing. Resolve package name. This is also one of the tedious task. Android Studio already do a lot of refactoring but some part left. Make sure your manifest file contains correct name. The best way to refactor your package name in xml file is to ctrl+Shift+f in Ubuntu or Edit → Find → Find in path in Android Studio. Then search old package name and replace it with new. You can use alt+ j for multi cursor as well. Clean and rebuild project. Run app at each step so that you can catch the error at a point. Also use debugger for debugging. Resources Migrate to Android Studio:…

Continue ReadingPhimpme: Merging several Android Projects into One Project