Friday May 16, 2008
Server-side image processing with JRuby-on-Rails and the Java 2D API
One of the many advantages of creating Rails applications with JRuby is the access that JRuby gives you to the rich set of Java libraries available in the Java platform.
This blog entry provides step-by-step instructions for creating a simple Rails application that uses the Java 2DTM API to perform server-side image processing. It also shows you how to install and use the GlassFishTM v3 Gem, which contains only the GlassFish v3 kernel, Grizzly, and other utilities, thereby giving you an application server with a smaller size and a faster start-up time.
Although Rails is intended for developing database-backed web applications, this application does not use a database. Many think that it is better to use the file system rather than a database to store binaries. I'll leave it up to you whether you use a database or not for that. In any case, this blog entry focuses on taking advantage of JRuby to access Java platform libraries from a Rails application.
Ruby-bin-1.1.zip from jruby.codehaus.org and unpack the zip file.
jruby -S gem install rails
jruby -S gem install glassfish
<JRUBY_INSTALL>/samples.jruby -S rails photo
photo directory you just created.jruby script/generate controller home index
<JRUBY_INSTALL>/samples/photo/config/environment.rb file in a text editor.config.frameworks -= [ :active_record, :active_resource, :action_mailer ]
To set up the UI, do the following:
<JRUBY_INSTALL>/samples/photo/public/images.
<JRUBY_INSTALL>/samples/photo/app/views/home/home.html.erb in a text editor.
<html>
<body>
<img src="../../images/kids.jpg"/><p>
<% form_tag :action => 'seeimage' do -%>
<%= select_tag "operation",
"<option selected='selected'>Grayscale</option>
<option>Negative</option>
<option>Brighten</option>
<option>Sharpen</option>
%>
<<% end -%>
</body>
</html>
Here you're using the form tag and select_tag helpers that Rails provides. It's a good idea to use the helpers rather than to write this HTML by hand because the helpers take care of a lot of extra stuff you'd have to add if you wrote the HTML yourself. When you run the application, just view the source of the page and you'll see what HTML the helpers generate for you. Check out Ruby on Rails Manual ActionView::Helpers for more information on the various helpers for views.
From the combobox on this page, the user can select from four different image effects: Grayscale, Negative, Brighten, and Sharpen. The selected name of the effect is saved into the operation variable and is passed as a request parameter to the seeimage action of the controller. The action will use this request parameter to execute the appropriate image-processing code.
While adding the Ruby code that performs the image processing to the controller, you'll learn the following concepts involved in using Java libraries in a Rails application:
java.io and javax.imageio packages
Graphics2D object from the buffered image so that you can draw the processed image.
<JRUBY_INSTALL>/samples/photo/app/controllers/hello_controller.rb in a text editorHomeController class declaration:
include Java
To add the constants you need for this application, do the following:
include Java statement, add the following constant declarations in your controller:
BI = java.awt.image.BufferedImage CS = java.awt.color.ColorSpace IO = javax.imageio.ImageIONow you can use the constant to reference the class later, as shown by this line:
bi2 = BI.new(w, h, BI::TYPE_INT_RGB)
import statement:
import java.awt.image.BufferedImage ... bi2 = BufferedImage.new(w, h, BufferedImage::TYPE_INT_RGB)
include_class statement:
include_class 'java.awt.image.BufferedImage'
filename = "#{RAILS_ROOT}/public/images/kids.jpg"
file = java.io.File.new(filename)
index.html.erb, and so you need an action called index. As I explained in the section on creating the UI, the form submits to the seeimage action in the controller. Normally, you would need a page called seeimage.html.erb to map to this action. But, in this case, the controller will stream the image to the browser, and so you need actions called index and seeimage, but you don't need a view that maps to seeimage.
HomeController class declaration and after the constants you added in the previous section, add a seeimage action:
def seeimage end
seeimage action, add an index action:
def index end
param method, which returns the parameters in a hash.
The operation request parameter has the value the user selected from the menu on index.html.erb. To get the value of operation, do the following:
seeimage action, read the value of the operation request parameter into a variable called @data:
@data = params[:operation]
BufferedImage object so that you can perform operations on the image.
seeimage action, right after the assignment of the operation request parameter into the @data variable, add the following code:
filename = "#{RAILS_ROOT}/public/images/kids.jpg"
imagefile = java.io.File.new(filename)
bi = IO.read(imagefile)
w = bi.getWidth
h = bi.getHeight
bi2 = BI.new(w, h, BI::TYPE_INT_RGB)
big = bi2.getGraphics
big.drawImage(bi, 0, 0, nil)
bi = bi2
File object.ImageIO class to store the image file into memory as a BufferedImage object so that you can perform operations on it.
BufferedImage with the preferred size and bit-depth to facilitate image processing.
Graphics2D object from the new BufferedImage object so that the graphics context, or drawing surface, has the proper size.
Graphics2D object to draw the original buffered image to the graphics context.
As you can see, referencing Java classes and methods from Ruby code is not much different from doing it from Java code. Notable differences are the following:
bi is a BufferedImage object because that's what the read method of ImageIO returns.
nil instead of null to represent a null value.
TYPE_INT_RGB field of BufferedImage:
BI::TYPE_INT_RGB
@data, you can write a case statement that creates the appropriate filter based on the value of @data. Each condition of the case statement uses a different class from the Java 2D API that can be used to perform a particular image-filtering operation. All of the classes implement BufferedImageOp. For more detail on image filtering in Java 2D, see
Using Java 2D's Image Processing Model.
This section goes into some detail about Java 2D image processing. If you're more interested in using Java libraries with Ruby code rather than the Java 2D API, just look for the Ruby_Info tag delimeters.
op = nil
case statement:
case @data
when "GrayScale"
colorSpace = CS.getInstance(CS::CS_GRAY)
op = java.awt.image.ColorConvertOp.new(colorSpace, nil)
when "Negative"
lut = Array.new
for j in 0..255
lut[j] = 256-j
end
jlut = lut.to_java :byte
blut = java.awt.image.ByteLookupTable.new(0, jlut)
op = java.awt.image.LookupOp.new(blut, nil)
when "Brighten"
op = java.awt.image.RescaleOp.new(1.4, -25, nil)
when "Sharpen"
data = [-1, 0, -1, 0, 5, 0, -1, 0, -1]
dataFloat = data.to_java :float
sharpen = java.awt.image.Kernel.new(3, 3, dataFloat)
op = java.awt.image.ConvolveOp.new(sharpen)
end
case statement is similar to the switch statement in the Java programming language, but is more powerful and flexible, partly because it internally tests for multiple conditions at once. For example, one condition of the statement can do a string comparison while another condition can perform regular expression matching, but that's beyond the scope of this blog.</Ruby_Info>
This case statement has a lot going on. Let's take it one piece at a time.
case statement uses ColorConvertOp to convert the color model of the image to grayscale, essentially making it a black-and-white image instead of a color image:
The Java 2D API provides a set of color spaces, such as CS_GRAY and CS_CMYK. You just need to create a new ColorConvertOp instance and give it your chosen color space.
LookupOp class to create a negative of the original image:
The LookupOp class uses a lookup table to filter the color values of pixels from a source image to a destination image. A pixel's color is made up of three components: red, green, and blue, each of which is represented by a value within the 8-bit range, 0-255.
To produce the negative of an image, you need to create a lookup table that has the values 0-255 in the reverse order so that each pixel's color will be set to the color's complement, as the following for loop does:
lut = Array.new for j in 0..255 lut[j] = 256-j endThis example uses only one lookup array, which means that it will be used to convert the colors of all three of the color components of each pixel. If you want, you can provide separate arrays for each color component so that each is converted in a different way.
<Ruby_Info>
The preceding code uses a Ruby array and a for loop. As with other variables in Ruby, you don't need to declare the type of the array, nor do you need to initialize it to a certain length. Same thing with the for loop: you don't need to initialize the iteration variable. And you don't need to explicitly increment it either. Finally, to indicate the range for the for loop, you just give the starting value and ending value of the iteration variable, separated by two dots.
After the for loop exits, you have a Ruby array. What you need to do is convert it into a Java array so that you can use the array with Java libraries. To convert the array, you use the to_java function and indicate the type that you want to assign to the array:
jlut = lut.to_java :byte
</Ruby_Info>
Now that you have converted the Ruby array to a Java array, you can use it to create a lookup table and pass the lookup table to an instance of LookupOp:
blut = java.awt.image.ByteLookupTable.new(0, jlut) op = java.awt.image.LookupOp.new(blut, nil)
RescaleOp to change the brightness or saturation of the image by applying a multiplier and an offset. The photo example uses RescaleOp to increase the brightness by 40% and shift the color values of each pixel 25 points to the lower part of the range (towards black) to make the image look a little more saturated:
op = java.awt.image.RescaleOp.new(1.4 -25, nil)After processing the image with this filter, you'll get the following image:
The way you perform convolution with the Java 2D API is by creating a Kernel object and then using it to construct a ConvolveOp object. The photo example uses a kernel that causes a sharpening effect:
To create the filter that will perform this sharpening effect, you would use the following code:
data = [-1, 0, -1, 0, 5, 0, -1, 0, -1] dataFloat = data.to_java :float sharpen = java.awt.image.Kernel.new(3, 3, dataFloat) op = java.awt.image.ConvolveOp.new(sharpen)Here again, you need to convert the Ruby array into a Java array before using it to create a
Kernel object.
The following matrix would give you the edge-detection effect:
[1, 0, 1, 0, -4, 0, 1, 0, 1]Here's the result of using this matrix on our example image:
dest = op.filter(bi, nil) big.drawImage(dest, 0, 0, nil);The
op variable is the object that represents the image filtering operation from the previous section. The dest variable represents the filtered buffered image.
read method of ImageIO read the image file into a buffered image, you can use the write method to write the filtered buffered image back into a file, or in the case of this example, an output stream, which you can then use to stream the file to the client.
os = java.io.ByteArrayOutputStream.new IO.write(dest, "jpeg", os) string = String.from_java_bytes(os.toByteArray) send_data string, :type => "image/jpeg", :disposition => "inline", :filename => "newkids.jpg"
send_data to stream it to the browser.
If you prefer to save the image to a file rather than a stream and save the file to disk, you can use send_file instead of send_data:
send_file writefilename, :type => 'image/jpg', :disposition => 'inline'
jruby -S glassfish_rails photo
http://localhost:3000/home/index
That's all there is to it. For more information on JRuby, Ruby-on-Rails, and the Java 2D API, visit the following links:
Posted at 01:15PM May 16, 2008 by jenniferb in Sun | Comments[20]
Posted by Arun Gupta's Blog on May 19, 2008 at 06:31 AM PDT #
This entry inspired me to add some methods to image_voodoo (jruby-extras) imaging processing library. I also added a blog entry showing how it could do something similiar to what you did in this entry:
http://www.bloglines.com/blog/ThomasEEnebo?id=50
-Tom
Posted by Thomas E Enebo on May 20, 2008 at 08:14 AM PDT #
Hi Thomas,
Thanks for your feedback. We writers always like it when we can help improve the quality of software.
Jennifer
Posted by Jennifer on May 21, 2008 at 05:18 PM PDT #
Hi Jennifer, great article!
I'm coming from the Ruby side but it's very informative to see what you think needs to be explained to people coming to this from Java.
Regarding Rubyisms .. here's a simple way to create the lut table -- I like how it reads better than the for loop.
lut = (0..255).to_a.reverse
creates this Array:
[255, 254, 253, ... 0]
You probably know this but I thought some of your readers might enjoy the idea.
Explanation:
0..255 is a range object
The Range class mixes in all the methods defined in the Enumerable Module including the method to_a (convert to an array).
Parens need to be put around the range object in order for the parser to properly recognize the intended receiver for the 'to_a' message. Without parens the parser will assume the receiver is the number object 255.
Then the message 'reverse' is sent to the new Array object which reverses the order originally generated when the range object was converted to an Array.
Posted by Stephen Bannasch on May 21, 2008 at 08:22 PM PDT #
Thanks, Stephen. No, I didn't know about that easier way to create the lut table. I'll have to mention that in the entry when I get a chance. I'm actually very new to Ruby. I owe a great debt to folks on the #jruby IRC channel for helping me out.
Posted by Jennifer on May 22, 2008 at 02:51 AM PDT #
<a href="http://rizo.codiego.com/">リゾートバイト</a> <a href="http://elbruz.kind7.biz/">自動車保険</a> <a href="http://pastel.aodiego.net/">ヒルズコレクション</a> <a href="http://scalp-d.aodiego.net/">スカルプDシャンプー</a> <a href="http://hillz.aodiego.net/">ヒルズダイエット</a> <a href="http://xn--n-pfuj3b1czif2l.seesaa.net/">パステルゼリー</a> <a href="http://xn--pckhnj3jpfxak0e.269g.net/">ヒルズコレクション</a>
<a href="http://xn--pckhnj3jpfxak.seesaa.net/">ヒルズダイエット</a>
Posted by ken on June 02, 2008 at 08:29 PM PDT #
assas
Posted by 59.90.19.42 on August 23, 2008 at 12:01 AM PDT #
Good collection and submission!
Regards
SBL - BPO Services|www.saibposervices.com
Posted by BPO Services on October 28, 2008 at 04:19 AM PDT #
[http://www.ireneblea.com/kinnsi/ 錦糸眼科の評判・口コミ・うわさ]
[http://www.sostips.com/kinnsi/ 錦糸眼科]
[http://www.wolfpackden.com/ 基礎代謝]
[http://www.2007senkyo.jp/pc/re-sikku/ レーシック 失敗]
[http://www.2007senkyo.jp/pc/fx/ FX比較]
[http://www.2007senkyo.jp/pc/gold/ ゴールドカード]
[http://dental-job.jp/re-sikku/ レーシック]
[http://dental-job.jp/goldcard/ ゴールドカード]
[http://dental-job.jp/fx/ FX初心者]
[http://dental-job.jp/kinnsi/ 錦糸眼科]
[http://dental-job.jp/kanagawa/ 神奈川クリニック眼科]
[http://www.2007senkyo.jp/pc/kinnsi/ 錦糸眼科]
[http://www.2007senkyo.jp/pc/kanagawa/ 神奈川クリニック眼科 レーシック]
[http://www.chinagate.jp/kinnsi/ 錦糸眼科]
Posted by mikkyo on November 13, 2008 at 10:23 PM PST #
SEO (or come grinding engine optimization) is to rewrite the web page to appear higher in search results for a particular search engine. Its technology. Also known as search engine optimization. The English "Search Engine Optimization" to take initial measures which are known as the SEO. Search engine optimization has become a target, Google often. The foreign (especially American) by the high market share in Google. In Japan, Yahoo! For many users of the search, Yahoo! Is focused search measures.
Posted by SEO on January 28, 2009 at 06:24 PM PST #
http://www.gunow.net
http://www.vangsof.com
http://www.voview.org
http://www.wampipirik.com
http://www.waroom.org
http://www.totown.org
http://www.abduet.com
http://www.pustudy.com
http://www.webnot.org
http://www.cufire.com
http://www.wfolk.net
http://www.fufire.com
http://www.ceratin.net
http://www.srisen.com
http://www.nabody.com
http://www.kenmind.com
http://www.byobizz.org
http://www.strykertrauma.biz
http://www.bchour.com
http://www.vofolk.com
http://www.vostaff.com
http://www.chartbc.com
http://www.hupoint.com
http://www.om-shiv.com
http://www.simgle.org
http://www.ikyo9.com
http://www.fisz.info
http://www.pudepot.com
http://www.hippc.net
http://www.gprekyba.com
http://www.exdale.com
http://www.joicity.com
http://www.ignightseattle.com
http://www.enmage.com
http://www.tjzhuyou.com
http://www.futsubay.com
http://www.consfry.com
http://www.wupoint.com
http://www.XJXUELIAN.COM
http://www.wuquick.com
http://www.xiday.org
http://www.kocable.net
http://www.lifairy.com
http://www.enjoywd.com
http://www.bctroop.com
http://www.popeo.net
http://www.kennkoou.com
http://www.kodisk.org
Posted by yy on January 28, 2009 at 06:25 PM PST #
http://month134.blogspot.com/2009/03/blog-post.html
http://month134.blogspot.com/2008/10/btbt.html
http://month135.blogspot.com/2009/03/blog-post.html
http://month135.blogspot.com/2009/02/blog-post.html
http://month135.blogspot.com/2008/10/200815.html
http://month133.blogspot.com/2008/10/blog-post.html
http://month133.blogspot.com/2009/02/blog-post.html
http://month133.blogspot.com/2009/03/blog-post.html
http://month2036.blogspot.com/2008/10/foxy.html
http://month2036.blogspot.com/2009/02/foxy.html
http://month2036.blogspot.com/2009/03/foxy.html
http://month2035.blogspot.com/2008/10/blog-post.html
http://month2035.blogspot.com/2009/02/blog-post.html
http://month2035.blogspot.com/2009/03/nod32.html
http://month2034.blogspot.com/2008/10/tw2500.html
http://month2034.blogspot.com/2009/02/blog-post.html
http://month2034.blogspot.com/2009/03/directx90.html
http://month2033.blogspot.com/2009/03/blog-post.html
http://month2033.blogspot.com/2009/02/blog-post.html
http://month2033.blogspot.com/2008/10/blog-post.html
http://month2032.blogspot.com/2009/02/1.html
http://month2032.blogspot.com/2008/10/2008.html
http://month2032.blogspot.com/2009/03/foxy.html
http://month132.blogspot.com/2009/03/5.html
http://month132.blogspot.com/2009/02/613.html
http://month132.blogspot.com/2008/10/blog-post.html
http://month131.blogspot.com/2009/03/emule-0-48a-emule-vista-emule.html
http://month131.blogspot.com/2009/02/blog-post.html
http://month131.blogspot.com/2008/10/blog-post.html
http://month130.blogspot.com/2009/02/blog-post.html
http://month130.blogspot.com/2008/10/blog-post.html
http://month130.blogspot.com/2009/03/rmvb.html
http://month129.blogspot.com/2009/02/blog-post.html
http://month129.blogspot.com/2009/03/foobar2000.html
http://month129.blogspot.com/2008/10/blog-post.html
http://month128.blogspot.com/2009/03/skype-skype.html
http://month128.blogspot.com/2009/02/11.html
http://month128.blogspot.com/2008/10/2008.html
Posted by fdf on March 03, 2009 at 06:02 PM PST #
http://you-tubehk.blogspot.com/
http://skypetw.blogspot.com/
http://tw-kmplayer.blogspot.com/
http://xunlei-tw.blogspot.com/
http://bt-tw.blogspot.com/
http://cs-cs16.blogspot.com/
http://winrar3-tw.blogspot.com/
http://nds-tw.blogspot.com/
http://twkmplayer.blogspot.com/
http://vista-tw.blogspot.com/
http://jojo-tw.blogspot.com/
http://emule047-tw.blogspot.com/
http://directx-90.blogspot.com/
http://office2007-tw.blogspot.com/
http://tw-vista.blogspot.com/
http://bosexe.blogspot.com/
http://rmvb-tw.blogspot.com/
http://bosstw.blogspot.com/
http://java-tw.blogspot.com/
http://tw-games.blogspot.com/
http://photoimpat.blogspot.com/
http://kmplayer2009.blogspot.com/
http://online-tw.blogspot.com/
http://sao-omline.blogspot.com/
Posted by fdf on March 03, 2009 at 06:02 PM PST #
http://you-tubehk.blogspot.com/
http://skypetw.blogspot.com/
http://tw-kmplayer.blogspot.com/
http://xunlei-tw.blogspot.com/
http://bt-tw.blogspot.com/
http://cs-cs16.blogspot.com/
http://winrar3-tw.blogspot.com/
http://nds-tw.blogspot.com/
http://twkmplayer.blogspot.com/
http://vista-tw.blogspot.com/
http://jojo-tw.blogspot.com/
http://emule047-tw.blogspot.com/
http://directx-90.blogspot.com/
http://office2007-tw.blogspot.com/
http://tw-vista.blogspot.com/
http://bosexe.blogspot.com/
http://rmvb-tw.blogspot.com/
http://bosstw.blogspot.com/
http://java-tw.blogspot.com/
http://tw-games.blogspot.com/
http://photoimpat.blogspot.com/
http://kmplayer2009.blogspot.com/
http://online-tw.blogspot.com/
http://sao-omline.blogspot.com/
http://month134.blogspot.com/2009/03/blog-post.html
http://month134.blogspot.com/2008/10/btbt.html
http://month135.blogspot.com/2009/03/blog-post.html
http://month135.blogspot.com/2009/02/blog-post.html
http://month135.blogspot.com/2008/10/200815.html
http://month133.blogspot.com/2008/10/blog-post.html
http://month133.blogspot.com/2009/02/blog-post.html
http://month133.blogspot.com/2009/03/blog-post.html
http://month2036.blogspot.com/2008/10/foxy.html
http://month2036.blogspot.com/2009/02/foxy.html
http://month2036.blogspot.com/2009/03/foxy.html
http://month2035.blogspot.com/2008/10/blog-post.html
http://month2035.blogspot.com/2009/02/blog-post.html
http://month2035.blogspot.com/2009/03/nod32.html
http://month2034.blogspot.com/2008/10/tw2500.html
http://month2034.blogspot.com/2009/02/blog-post.html
http://month2034.blogspot.com/2009/03/directx90.html
http://month2033.blogspot.com/2009/03/blog-post.html
http://month2033.blogspot.com/2009/02/blog-post.html
http://month2033.blogspot.com/2008/10/blog-post.html
http://month2032.blogspot.com/2009/02/1.html
http://month2032.blogspot.com/2008/10/2008.html
http://month2032.blogspot.com/2009/03/foxy.html
http://month132.blogspot.com/2009/03/5.html
http://month132.blogspot.com/2009/02/613.html
http://month132.blogspot.com/2008/10/blog-post.html
http://month131.blogspot.com/2009/03/emule-0-48a-emule-vista-emule.html
http://month131.blogspot.com/2009/02/blog-post.html
http://month131.blogspot.com/2008/10/blog-post.html
http://month130.blogspot.com/2009/02/blog-post.html
http://month130.blogspot.com/2008/10/blog-post.html
http://month130.blogspot.com/2009/03/rmvb.html
http://month129.blogspot.com/2009/02/blog-post.html
http://month129.blogspot.com/2009/03/foobar2000.html
http://month129.blogspot.com/2008/10/blog-post.html
http://month128.blogspot.com/2009/03/skype-skype.html
http://month128.blogspot.com/2009/02/11.html
http://month128.blogspot.com/2008/10/2008.html
http://xiha.sparkletrade.com
http://tw.sparkletrade.com
http://month136.blogspot.com/2008/10/blog-post.html
http://month136.blogspot.com/2009/02/blog-post.html
http://month136.blogspot.com/2009/03/blog-post.html
http://month137.blogspot.com/2008/10/blog-post.html
http://month137.blogspot.com/2009/03/blog-post.html
http://month137.blogspot.com/2009/02/blog-post.html
http://empire-lyrics.blogspot.com/2009/03/kikikoko.html
http://empire-lyrics.blogspot.com/2009/02/blog-post.html
http://empire-lyrics.blogspot.com/2008/10/blog-post.html
http://msn2018.blogspot.com/2009/03/mv-go-mv.html
http://msn2018.blogspot.com/2009/02/rain.html
http://msn2018.blogspot.com/2008/10/msn.html
http://dance2018.blogspot.com/2009/03/online.html
http://dance2018.blogspot.com/2008/10/blog-post.html
http://dance2018.blogspot.com/2009/02/rain.html
http://free-count.blogspot.com/2009/03/blog-post.html
http://free-count.blogspot.com/2009/02/blog-post.html
http://free-count.blogspot.com/2008/10/blog-post.html
http://ear-touch.blogspot.com/2009/03/blog-post.html
http://ear-touch.blogspot.com/2009/02/16.html
http://ear-touch.blogspot.com/2008/10/cs.html
Posted by fdfd@yahoo.com on March 10, 2009 at 12:29 AM PDT #
あなたは今の性生活に満足していますか<a href="http://sexperte.net/">セフレ募集</a>満足してみませんか?
<a href="http://deaitai-mail.net/womanbbs/">セフレ募集</a>意外と簡単に作れてしまうのです
<a href="http://2dllc.com/teensbbs/ ">セフレ募集を</a>作ったことない人は安心してください
<a href="http://advancedwd.com">セフレ募集</a>を作れる安心安全無料サイトを紹介したいとおもいます。
Posted by セフレ募集 on March 16, 2009 at 08:30 PM PDT #
http://www.yndryl.com
Posted by fsdf on March 29, 2009 at 10:53 PM PDT #
http://gotanda.fuzokustyle.jp/
http://shibuya.fuzokustyle.jp/
http://machida.fuzokustyle.jp/
http://chiba.fuzokustyle.jp/
http://ikebukuro.fuzokustyle.jp/
http://ueno.fuzokustyle.jp/
http://kinshicho.fuzokustyle.jp/
http://shinjuku.fuzokustyle.jp/
http://saitama.fuzokustyle.jp/
http://yokohama.fuzokustyle.jp/
Posted by 風俗 on August 21, 2009 at 10:57 PM PDT #
http://inoki.info/
http://kanshoku.info/
http://hatabou.org/
Posted by inoki on September 24, 2009 at 04:45 AM PDT #
http://www.skycloud.cn
Posted by xinyun on October 25, 2009 at 07:06 PM PDT #
http://emobile-service.com/
http://kireininaru.info/
http://tossy.info/
http://norishio.info/
http://chapatu.info/
http://atui.info/
Posted by emob on October 28, 2009 at 04:51 PM PDT #