Understand the UIImage Resize

Some plain talk first.

During the past few months, I have changed my job. 

Now I work for Media Technology Labs (MTL) as an Intrapreneur. MTL is the R&D department belonging to Recruit holdings.

It is a great place, full of passionate people . I believe I could push myself forward in such a place.

I am still in the phase of searching my own position in the team. Currently I am adding testing framework to the existing projects and refactoring the existing projects. It is heavy work but fun.

During the review, I noticed some codes handling photo taking and resizing were written without full consideration. They work but in a  tweaked way. I prefer a more logic way.  I decided to write a post on it. Any feedback is welcome.

I used to be involved in several projects with Photo-taking function. It bothered me a lot as well. I would blame Apple’s peculiar design  (^__^).

Without further ado, let’s get into the theme.

Here is the problem description:

Our goal is to take a photo, resize it and save it into local filesystem.

Suppose  we hold iPhone with home button on the bottom and take a picture.

If we directly save the original image get from

 imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info

We will get a image  as follows:

original

This is bad and undesirable.

There must be something wrong .  We print out  taken photo’s imageOrientation and find it is UIImageOrientationRight instead of the “UP” direction.

Even though you take the photo in up direction, you get a “Non-UP” photo. It is life. It is not easy. What you want is not what you get. But don’t worry, Apple gives its  definition on this. It means you have to rotate 90 clockwise to get a right image. https://developer.apple.com/library/ios/documentation/uikit/reference/UIImage_Class/Reference/Reference.html 

Great, we figure out what we need to do next is to rotate the image first, then  resize it. But how? There is a bunch of codes and articles in the internet which handle rotation and resize. The most famous one I know is http://vocaro.com/trevor/blog/2009/10/12/resize-a-uiimage-the-right-way/

I  followed  the codes from it. It works and I suggest you read it first. It helps you to understand the following statement easier. You can also download my revised version  in github as a reference.

The borrowed code works but the problem is I still don’t understand the mechanism behind the scene. I don’t know how to think the coordinate transformation such as

if (sourceImage.imageOrientation == UIImageOrientationRight) {

CGContextRotateCTM (bitmap, radians(-90));

CGContextTranslateCTM (bitmap, -targetWidth, 0);

}

It is not healthy to be a copy-paste programmer, so I did some thinking on the code and the mechanism.

Here are some basic facts you have to remember  before we dive into the code:

1.  If we check CGImageRef you generated from taken photo, we would  find the width is always bigger than height.

2. Bitmap is our painting destination( You could think it as a device screen). The size of it needs to be same with what we want (Desired Image Size).

Based on the above facts, we could create a correct bitmap like this

bitmap = CGBitmapContextCreate(NULL, targetSize.width, targetSize.height, CGImageGetBitsPerComponent(imageRef), CGImageGetBytesPerRow(imageRef), colorSpaceInfo, bitmapInfo);

Then we start to transform our user space (the image) and map it to the bitmap. A easy way of thinking on this is to map the pixels of the origin of two coordinate.

We now have UIImageOrientationLeft  (The image), and we want it to be  UIImageOrientationUp (The desired image in bitmap). One big difference between the two images is that the pixels at origin  are not mapped.

First we imagine a coordinate with origin at the left bottom of UIImageOrientationLeft. It is the coordinate of our user space.

What we want to achieve is to transform this coordinate and move the origin to right bottom of UIImageOrientationLeft (Of course, the entire image need to be   within the new coordinate.).  If the origin of the coordinate is located at right bottom, it means the (0,0) point will be the pixel at the right bottom.  When the image is drew onto the bitmap, the left bottom of bitmap – (0,0)  is mapped by this new origin. And it is what we want.

The operations on the coordinate of user space  are a counter-clockwise 90 rotate and a move with distance of CGImageRef’s width as mentioned above.

Other situations can be considered in the similar way.

To sum up, the key is to understand the mapping between user space and destination (Here it is bitmap).

Hope this post helps.

 

PS: I found some illustrations aren’t shown in the paragraph, please click them to see the original ones.

Apple developer conf.

First time to join a conference.
A lot to study for sure

工作准备时

今天下午想了想即将到来的各种coding面试。

还是从头复习下一些东西好。

于是瞅了瞅Ruby, javascript和jquery。

心里没有底,果然还是需要时间看看算法和C++.

 

给twitter投简历连机会都木有,太菜了我。

加油加油,一步步来。。。

 

另外某公司给的面试题是写一个twitter的客户端,我顿时傻眼了。这是个什么节奏。

时间感

大约委托了三拨人在帮我找下家。

 

于是时间就基本没了,需要做webtest啊,需要学习日语啊,需要拣一下算法和概率啊,不然不靠谱啊。

 

加油吧!只能缩减睡眠了。

 

 

离职

交了离职报告。
すっかりしました。

Move on, bro

面试小记

最近想想创业做了两年了,到现在团队也不满意,事业也没发展,最重要的是自己觉得不开心了。

正好在linkedin上有猎头找我,我想了几天,决定还是干干脆脆的再找个适合自己发展的平台继续发展。

于是就有了今天的这次面试。

好久没面试了,并且又是我最不擅长的日语,还是有点紧张的。

对方问了以下的问题:

1,现在的转职进行的咋样了?

2.  主要擅长什么技术?

3.  对UDID有利用吗?如何应对jailbreak?(不大懂这个)

4. 数据传输的安全面是如何做的?我傻乎乎的说了HMAC

5. 在开发的程序中xx界面是如何做到高效的?

6. Android那边的开发如何做?

7. 是否介意做服务器和Android?

8. 还有啥问题不?

我基本都回答了,有些描述的不好,有些应该是说多了。

我的问题在于说了不少多余的话:感觉得少说点为啥要离开当前公司的话(如果没问到的时候),多说写技术层面的问题。主要是开发过程中的问题都是比较琐碎的,花时间下去就一定可以解决掉,我都没咋上心,还是要准备一下。

下回就说ios的图像处理那块,orientation。

以及说目前开发的一些限制,需要兼容低版本。

总之,试手先。

晚上再弄下简历,月底跟老板摊牌。

给自己一个月时间充电,然后找下一个平台。一定没问题哈!

加油!

Core Data Memo

今天花了点时间看了下Core data。

概括的说,core data非常牛叉,是苹果给出的一个本地存储的solution。

我猜底层应该还是sql那套,但从可以保存几乎所有尺寸的文件来说,会不会有可能还有一些智能判断,把大文件存到了磁盘上。(当然按stanford的老头说的,他可能不会把video用core data 存。)

用起来很方便,主要是要领会苹果的context精神。

用UIDocument来做,找出当前的context,然后对managedobject进行操作。

Xcode可以很方便的生成managedObject的子类,从而使用用dot来访问其中的属性。

应该会大大减轻工作量。

有几点需要注意,

数据的操作,document的创建和save都是异步的。

也就是说core data 的多线程操作容易出问题。

老头给了一个很高端的做法就是在当前context的parentconttext里调用performBlock这个函数,可以保证线程的安全。具体由于没有实验过,也不是特别理解。这点需要在之后的实践中试试。

今晚准备将一个小项目再push forward一下。

加油。

Idea

Ideas are there, not hiding themselves.

They worth nothing. There are no difference between them.

Our preference of  judging an idea good or bad makes no sense.

All we really need is the operation, the force turns an idea to a real product.

You will find every properly made product has its unique meaning, thus every idea is good.

If you don’t know whether it is a good idea or not, do it.

牛逼的Knuth

Knuth 对于从事码农工作的人真是神一样的存在。

今天学习下他的网站。发现他真的是一个超级可爱的老头。

只有28个学生(好幸福的学生啊),也不准备再advice谁。但是谁要是能在二到三周内答出他在computing musings里的一个问题,就可以让他看论文。(http://www-cs-faculty.stanford.edu/~uno/musings.html)

老头还爱钢琴和风琴(管风琴的样子),还邀请人和他一起表演四手感情。这得多多才多艺啊。

以下是他推荐的非技术类书单,回头找找。

  • Life A Users Manual by Georges Perec (perhaps the greatest 20th century novel)
  • Gaudy Night by Dorothy L Sayers (captures Oxford high-table small-talk wonderfully)
  • An Instance of the Fingerpost by Iain Pears (also Oxford but in the 1660s)
  • Death of a Salesperson by Robert Barnard (who is at his best in short stories like these)
  • The Haj by Leon Uris (great to read on a trip to Israel)
  • Marjorie Morningstar by Herman Wouk (in-depth characters plus a whole philosophy)
  • On Food and Cooking by Harold McGee (applied biochemistry in the kitchen)
  • Food by Waverley Root (his magnum opus, a wonderful history of everything delicious)
  • The Golden Gate by Vikram Seth (the Great California Novel, entirely in 14-line sonnets)
  • The Age of Faith by Will Durant (volume 4 of his series, covers the years 325–1300)
  • Efronia by Stina Katchadourian (diaries and letters of a remarkable Armenian woman)
  • The Man Who Knew Infinity by Robert Kanigel (biographies of Ramanujan and Hardy)
  • Hackers by Steven Levy (incredibly well written tale of our times)
  • The Abominable Man by Maj Sjöwall and Per Wahlöö (one of their brilliantly Swedish detective novels)
  • Blasphemy by Douglas Preston (the best novel to deal with “science versus religion” that I’ve ever encountered)
  • Blacklist by Sara Paretsky (a brilliant characterization of the tragic state of politics and class relations in America that also happens to be an action-packed murder mystery)
  • The Travels of Ibn Battutah edited by Tim Mackintosh-Smith (fascinating and eye-opening journal by a 14th-century Muslim scholar)
  • Murder in the Museum of Man by Alfred Alcorn (delicious caricature of academic follies)
  • America (The Book): Teacher’s Edition by Jon Stewart (has graffiti even better than the marginal notes in Concrete Mathematics)
  • Feynman by Jim Ottaviani and Leland Myrick (vivid, witty, hilarious, poignant: I laughed, I cried, I learned; demonstrates the unreasonable effectiveness of a graphic novel)

这辈子也要努力,老了也有可写的!

Goodbye, dash blogging

Writing blogs was  a dash for me.

In a short period like one month, the desire of expression would  burst from my body. I couldn’t control it.  It then led me to carefully look at my life  and compose some naive feelings on my space.

After this period, my inner peace returned. In another word, I was tired of posting personal affairs. It is like I am attending a marathon.  I ran the first 1000 meter pretty well and fast. Then I  stopped to walk because I was tired. People were passing by, the track in front seems endless.

I know  I wouldn’t reach the goal by walk, so I tried to pick up the competition and run again.  At this time, lazy goblin came and told me such as I am too busy these days, no one is reading it anyway, there is no meaning to crapping on politics.  With the evil power of him, I continued to do no change. The worst part is that I didn’t feel guilty about it at all.

If human race has a superpower to comfort himself for any wrong,  I should have reached max level.

BUT  IT IS NOT RIGHT.

One thing I almost forgot is that blogging is for myself. I start to blog because I want to  record  my ideas and plain  life.  It helps me to reflect myself and move forward.  I can’t ditch it because of some silly excuses or just because the fever has gone.

Lately, I consider myself standing at a fork of my life and am hesitated to step forward. It is like my blogging experience, I dashed  before and got tired. I wanted to change but was stopped for some reasons.

It is time for me to throw useless pressure away, pack up necessaries  and take my adventure again.

Though I still don’t know what to do exactly , I decide to learn a little thing everyday and write it down on my blog.

No dash anymore, life is a marathon. I need to learn to preserve my energy and reach the goal.

Goodbye, old me.

 

Follow

Get every new post delivered to your Inbox.