cookbook.rdoc in free-image-0.6.2 vs cookbook.rdoc in free-image-0.7.0

- old
+ new

@@ -1,238 +1,249 @@ -= \Getting Started With \FreeImage -Below are various recipes to get you up and running with \FreeImage as quickly -as possible. The example images tcan be found in the -test/images directory. For more general information about \FreeImage, including -installation instructions, please refer to README.rdoc. - -== Loading An Image -The first step in using \FreeImage is to load an image. \FreeImage can load -images from files[rdoc-ref::FreeImage::File], strings[rdoc-ref::FreeImage::Memory] -or IO[rdoc-ref::FreeImage::IO] streams. The simplest way to do this is -via the FreeImage::Bitmap.open method: - - image = FreeImage::Bitmap.open('images/lena.tiff') - image = FreeImage::Bitmap.open(io_object) - image = FreeImage::Bitmap.open(FreeImage::Memory.new(string)) - -The open method also takes two additional optional parameters, format and flags, -that provide greater control over opening images if needed. - -The open method works similary to File.open, meaning you can also pass it a block. - - FreeImage::Bitmap.open('images/lena.png') do |image| - ... do some stuff.. - end - -Once the block completes, the image will be automatically freed for you. If you don't -pass block, then the image will be freed by Ruby's Garbage Collector once it goes out -of scope. For more information about memory management, refer to -the readme [rdoc-ref:README.rdoc]. - -Image[link:cookbook/lena.png] - -== Saving An Image -Now let's say you want to save the image to :png format. This is done -via the FreeImage::Bitmap.save method. The save method takes a destination, -which can be a file[rdoc-ref::FreeImage::File], string[rdoc-ref::FreeImage::Memory] -or IO[rdoc-ref::FreeImage::IO] stream, and an image format. - - image.save('images/lena.png', :png) - -== Creating a Thumbnail -Next, let's assume our application needs to show a list of thumbnails for the images - it stores. This can be done using the make_thumbnail[rdoc-ref:FreeImage::Modify.make_thumbnail] -method in the Modify[rdoc-ref:FreeImage::Modify] module. - - thumbnail = image.make_thumbnail(100) - thumbnail.save('images/lena_thumbnail.png', :png) - -Thumbnail[link:cookbook/lena_thumbnail.png] - -== Putting a Border Around a Thumbnail -Once we have created a thumbnail, let's outline it with a red border. There -are various approaches to do doing this. In the first approach, we'll use -the enlarge_canvas[FreeImage::Modify.enlarge_canvas] method. - - # Border size - border = 4 - - # Specify the color as red - color = FreeImage::RGBQuad.create(255, 0, 0) - - # Add 4 pixel red border around the thumbnail - thumbnail_border = thumbnail.enlarge_canvas(border, border, border, border, color) - thumbnail_border.save('images/lena_thumbnail_border_1.png', :png) - -ThumbnailBorderEnlarge[link:cookbook/lena_thumbnail_border_enlarge.png] - -In the second approach, let's create a image with a red background -and then paste it on top of our thumbnail: - - # Create a red image that is the same size as the thumbnail - red_image = FreeImage::Bitmap.create(thumbnail.width, thumbnail.height, thumbnail.bits_per_pixel) - red_image_new.fill_background(color) - - # Now copy a subimage from the thumbnail that is 2 borders less wide and tall - subimage = thumbnail.copy(border, border, thumbnail.width - border, thumbnail.height - border) - - # Now paste the subimage into the red image. Specify an alpha over 255 - # to disable alpha blending - red_image.paste(subimage, border, border, 300) - red_image.save('images/test1.png', :png) - thumbnail_border.save('images/lena_thumbnail_border_2.png', :png) - -ThumbnailBorderPaste[link:cookbook/lena_thumbnail_border_paste.png] - -== Resampling An Image -If you need additional control over how an image is resampled, use the -FreeImage::Bitmap#rescale method, which lets you specify a filtering -algorithm. To see how each filter works, let's scale up the thumbnail -by 400%. - - thumbnail = FreeImage::Bitmap.open('images/lena_thumbnail.png') - - FreeImage.enum_type(:filter).symbols.each do |filter| - rescaled = thumbnail.rescale(thumbnail.width * 4, thumbnail.height * 4, filter) - rescaled.save("images/lena_rescale_#{filter.to_s}.png", :png) - end - -RescaleBox[link:cookbook/lena_rescale_box.png] -RescaleBicubic[link:cookbook/lena_rescale_bicubic.png] -RescaleBilinear[link:cookbook/lena_rescale_bilinear.png] -RescaleBspline[link:cookbook/lena_rescale_bspline.png] -RescaleCatmullrom[link:cookbook/lena_rescale_catmullrom.png] -RescaleLanczos3[link:cookbook/lena_rescale_lanczos3.png] - -== Flipping An Image -The Transform modules lets you flip or rotate an image. Let's say you want to -flip your image horizontally: - - image.flip_horizontal - image.save('images/lena_flipped.png', :png) - -Thumbnail[link:cookbook/lena_flipped.png] - -== Rotating An Image -Next, let's rotate an image. Two methods are provide, FreeImage::Bitmap#rotate and -FreeImage::Bitmap#rotate_ex. The #rotate method is simpler to use: - - image = FreeImage::Bitmap.open('images/lena.png', :png) - - # Rotate the image 45 degrees using white as the background fill color - color = FreeImage::RGBQuad.create(255, 255, 255, 0) - rotated = image.rotate(45, color) - rotated.save("images/lena_rotate_45.png", :png) - -Thumbnail[link:cookbook/lena_rotate_45.png] - -Notice that the image size and geometry has changed? Thus, the #rotate -function is best for rotating and image 90, 180 or 270 degrees. - -Let's now rotate the image using the #rotate_ex method while using a mask: - - rotated = image.rotate_ex(45, 0, 0, image.width/2, image.height/2, true) - rotated.save("images/lena_rotate_ex_45_masked.png", :png) - -And now let's rotate the image without a mask, so data is filled in using -a mirroring algorithm: - - rotated = image.rotate_ex(45, 0, 0, image.width/2, image.height/2, false) - rotated.save("images/lena_rotate_ex_45_mirrored.png", :png) - -Thumbnail[link:cookbook/lena_rotate_ex_45_masked.png] -Thumbnail[link:cookbook/lena_rotate_ex_45_mirrored.png] - -Last, lets rotate the image around the top left corner: - - rotated = image.rotate_ex(45, 0, 0, 0, 0, true) - rotated.save("images/lena_rotate_ex_45_top_left.png", :png) - -Thumbnail[link:cookbook/lena_rotate_ex_45_top_left.png] - -== Compositing An Image -\FreeImage also lets you composite an image with a background color or another image. -Here is an example of compositing an image with the color green. - - image = FreeImage::Bitmap.open('images/sample.png') - color = FreeImage::RGBQuad.create(0, 255, 0, 0) - composite = image.composite_with_color(color) - composite.save("images/sample_composite_color.png", :png) - -Sample[link:cookbook/sample.png] -SampleCompositeColor[link:cookbook/sample_composite_color.png] - -== Manipulating An Image -\FreeImage also allows you to directly access each pixel in an image. -As an example, let's create an image that has a gradient from -blue in the top left corner to green in the bottom right - - image = FreeImage::Bitmap.create(300, 300, 24) - color = FreeImage::RGBQuad.new - - image.width.times do |x| - image.height.times do |y| - color[:green] = (x.to_f/image.width) * 255 - color[:blue] = (y.to_f/image.height) * 255 - image.set_pixel_color(x, y, color) - end - end - - image.save('images/gradient.png', :png) - -Gradient[link:cookbook/gradient.png] - -You can use a similar technique as another solution to drawing a border around a -thumbnail as discussed above. - -== Using Scanlines -Scanlines[rdoc-ref:FreeImage::Scanline] provide low level access to image data. -The only lower-level access is working with the actual raw bytes, which you can do -via the FreeeImage::Bitmap#bytes method, but its not recommended. - -A scanline represents one row of image data, starting from the bottom. Let's go back -to our example above of drawing a red border around a thumbnail. - - # Helper method - def set_to_red(color) - color[:red] = 255 - color[:green] = 0 - color[:blue] = 0 - end - - # Create a thumbnail - image = FreeImage::Bitmap.open('images/lena.png') - thumbnail = image.make_thumbnail(100) - - # Draw bottom border 4 pixels tall - (0..3).each do |index| - scanline = thumbnail.scanline(index) - scanline.each do |color| - set_to_red(color) - end - end - - # Draw top border 4 pixels tall - ((thumbnail.height - 5)..(thumbnail.height - 1)).each do |index| - scanline = thumbnail.scanline(index) - scanline.each do |color| - set_to_red(color) - end - end - - # We could skip top and bottom 4 scanlines since - # already drew them. - thumbnail.height.each do |index| - scanline = thumbnail.scanline(index) - # Draw left and right borders 4 pixels wide - (0..4).each do |index| - set_to_red(scanline[index]) - end - - ((thumbnail.width - 5)..(thumbnail.width - 1)).each do |index| - set_to_red(scanline[index]) - end - end - - thumbnail.save("images/lena_thumbnail_border_scanline.png", :png) - += \Getting Started With \FreeImage +Below are various recipes to get you up and running with \FreeImage as quickly +as possible. The example images tcan be found in the +test/images directory. For more general information about \FreeImage, including +installation instructions, please refer to README.rdoc. + +== Loading An Image +The first step in using \FreeImage is to load an image. \FreeImage can load +images from files[rdoc-ref::FreeImage::File], strings[rdoc-ref::FreeImage::Memory] +or IO[rdoc-ref::FreeImage::IO] streams. The simplest way to do this is +via the FreeImage::Bitmap.open method: + + image = FreeImage::Bitmap.open('images/lena.tiff') + image = FreeImage::Bitmap.open(io_object) + image = FreeImage::Bitmap.open(FreeImage::Memory.new(string)) + +The open method also takes two additional optional parameters, format and flags, +that provide greater control over opening images if needed. + +The open method works similary to File.open, meaning you can also pass it a block. + + FreeImage::Bitmap.open('images/lena.png') do |image| + ... do some stuff.. + end + +Once the block completes, the image will be automatically freed for you. If you don't +pass block, then the image will be freed by Ruby's Garbage Collector once it goes out +of scope. For more information about memory management, refer to +the readme [rdoc-ref:README.rdoc]. + +Image[link:cookbook/lena.png] + +== Saving An Image +Now let's say you want to save the image to :png format. This is done +via the FreeImage::Bitmap.save method. The save method takes a destination, +which can be a file[rdoc-ref::FreeImage::File], string[rdoc-ref::FreeImage::Memory] +or IO[rdoc-ref::FreeImage::IO] stream, and an image format. + + image.save('images/lena.png', :png) + +== Creating a Thumbnail +Next, let's assume our application needs to show a list of thumbnails for the images + it stores. This can be done using the make_thumbnail[rdoc-ref:FreeImage::Modify.make_thumbnail] +method in the Modify[rdoc-ref:FreeImage::Modify] module. + + thumbnail = image.make_thumbnail(100) + thumbnail.save('images/lena_thumbnail.png', :png) + +Thumbnail[link:cookbook/lena_thumbnail.png] + +== Putting a Border Around a Thumbnail +Once we have created a thumbnail, let's outline it with a red border. There +are various approaches to do doing this. In the first approach, we'll use +the enlarge_canvas[FreeImage::Modify.enlarge_canvas] method. + + # Border size + border = 4 + + # Specify the color as red + color = FreeImage::RGBQuad.create(255, 0, 0) + + # Add 4 pixel red border around the thumbnail + thumbnail_border = thumbnail.enlarge_canvas(border, border, border, border, color) + thumbnail_border.save('images/lena_thumbnail_border_1.png', :png) + +ThumbnailBorderEnlarge[link:cookbook/lena_thumbnail_border_enlarge.png] + +In the second approach, let's create a image with a red background +and then paste it on top of our thumbnail: + + # Create a red image that is the same size as the thumbnail + red_image = FreeImage::Bitmap.create(thumbnail.width, thumbnail.height, thumbnail.bits_per_pixel) + red_image_new.fill_background(color) + + # Now copy a subimage from the thumbnail that is 2 borders less wide and tall + subimage = thumbnail.copy(border, border, thumbnail.width - border, thumbnail.height - border) + + # Now paste the subimage into the red image. Specify an alpha over 255 + # to disable alpha blending + red_image.paste(subimage, border, border, 300) + red_image.save('images/test1.png', :png) + thumbnail_border.save('images/lena_thumbnail_border_2.png', :png) + +ThumbnailBorderPaste[link:cookbook/lena_thumbnail_border_paste.png] + +== Resampling An Image +If you need additional control over how an image is resampled, use the +FreeImage::Bitmap#rescale method, which lets you specify a filtering +algorithm. To see how each filter works, let's scale up the thumbnail +by 400%. + + thumbnail = FreeImage::Bitmap.open('images/lena_thumbnail.png') + + FreeImage.enum_type(:filter).symbols.each do |filter| + rescaled = thumbnail.rescale(thumbnail.width * 4, thumbnail.height * 4, filter) + rescaled.save("images/lena_rescale_#{filter.to_s}.png", :png) + end + +RescaleBox[link:cookbook/lena_rescale_box.png] +RescaleBicubic[link:cookbook/lena_rescale_bicubic.png] +RescaleBilinear[link:cookbook/lena_rescale_bilinear.png] +RescaleBspline[link:cookbook/lena_rescale_bspline.png] +RescaleCatmullrom[link:cookbook/lena_rescale_catmullrom.png] +RescaleLanczos3[link:cookbook/lena_rescale_lanczos3.png] + +== Flipping An Image +The Transform modules lets you flip or rotate an image. Let's say you want to +flip your image horizontally: + + image.flip_horizontal + image.save('images/lena_flipped.png', :png) + +Thumbnail[link:cookbook/lena_flipped.png] + +== Rotating An Image +Next, let's rotate an image. Two methods are provide, FreeImage::Bitmap#rotate and +FreeImage::Bitmap#rotate_ex. The #rotate method is simpler to use: + + image = FreeImage::Bitmap.open('images/lena.png', :png) + + # Rotate the image 45 degrees using white as the background fill color + color = FreeImage::RGBQuad.create(255, 255, 255, 0) + rotated = image.rotate(45, color) + rotated.save("images/lena_rotate_45.png", :png) + +Thumbnail[link:cookbook/lena_rotate_45.png] + +Notice that the image size and geometry has changed? Thus, the #rotate +function is best for rotating and image 90, 180 or 270 degrees. + +Let's now rotate the image using the #rotate_ex method while using a mask: + + rotated = image.rotate_ex(45, 0, 0, image.width/2, image.height/2, true) + rotated.save("images/lena_rotate_ex_45_masked.png", :png) + +And now let's rotate the image without a mask, so data is filled in using +a mirroring algorithm: + + rotated = image.rotate_ex(45, 0, 0, image.width/2, image.height/2, false) + rotated.save("images/lena_rotate_ex_45_mirrored.png", :png) + +Thumbnail[link:cookbook/lena_rotate_ex_45_masked.png] +Thumbnail[link:cookbook/lena_rotate_ex_45_mirrored.png] + +Last, lets rotate the image around the top left corner: + + rotated = image.rotate_ex(45, 0, 0, 0, 0, true) + rotated.save("images/lena_rotate_ex_45_top_left.png", :png) + +Thumbnail[link:cookbook/lena_rotate_ex_45_top_left.png] + +== Compositing An Image +\FreeImage also lets you composite an image with a background color or another image. +Here is an example of compositing an image with the color green. + + image = FreeImage::Bitmap.open('images/sample.png') + color = FreeImage::RGBQuad.create(0, 255, 0, 0) + composite = image.composite_with_color(color) + composite.save("images/sample_composite_color.png", :png) + +Sample[link:cookbook/sample.png] +SampleCompositeColor[link:cookbook/sample_composite_color.png] + +And here is an example of compositing two images together: + + image = FreeImage::Bitmap.open(image_path('sample.png')) + background = FreeImage::Bitmap.open(image_path('gradient.png')) + # Need to make sure the background image is the same size + background = background.rescale(image.width, image.height, :box) + composite = image.composite(background) + +Sample[link:cookbook/sample.png] +SampleCompositeColor[link:cookbook/sample_composite.png] + +== Manipulating An Image +\FreeImage also allows you to directly access each pixel in an image. +As an example, let's create an image that has a gradient from +blue in the top left corner to green in the bottom right + + image = FreeImage::Bitmap.create(300, 300, 24) + color = FreeImage::RGBQuad.new + + image.width.times do |x| + image.height.times do |y| + color[:green] = (x.to_f/image.width) * 255 + color[:blue] = (y.to_f/image.height) * 255 + image.set_pixel_color(x, y, color) + end + end + + image.save('images/gradient.png', :png) + +Gradient[link:cookbook/gradient.png] + +You can use a similar technique as another solution to drawing a border around a +thumbnail as discussed above. + +== Using Scanlines +Scanlines[rdoc-ref:FreeImage::Scanline] provide low level access to image data. +The only lower-level access is working with the actual raw bytes, which you can do +via the FreeeImage::Bitmap#bytes method, but its not recommended. + +A scanline represents one row of image data, starting from the bottom. Let's go back +to our example above of drawing a red border around a thumbnail. + + # Helper method + def set_to_red(color) + color[:red] = 255 + color[:green] = 0 + color[:blue] = 0 + end + + # Create a thumbnail + image = FreeImage::Bitmap.open('images/lena.png') + thumbnail = image.make_thumbnail(100) + + # Draw bottom border 4 pixels tall + (0..3).each do |index| + scanline = thumbnail.scanline(index) + scanline.each do |color| + set_to_red(color) + end + end + + # Draw top border 4 pixels tall + ((thumbnail.height - 5)..(thumbnail.height - 1)).each do |index| + scanline = thumbnail.scanline(index) + scanline.each do |color| + set_to_red(color) + end + end + + # We could skip top and bottom 4 scanlines since + # already drew them. + thumbnail.height.each do |index| + scanline = thumbnail.scanline(index) + # Draw left and right borders 4 pixels wide + (0..4).each do |index| + set_to_red(scanline[index]) + end + + ((thumbnail.width - 5)..(thumbnail.width - 1)).each do |index| + set_to_red(scanline[index]) + end + end + + thumbnail.save("images/lena_thumbnail_border_scanline.png", :png) + ThumbnailBorderScanline[link:cookbook/lena_thumbnail_border_scanline.png] \ No newline at end of file