1# Copyright 2014 The Chromium Authors. All rights reserved. 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5"""Provides implementations of basic image processing functions. 6 7Implements basic image processing functions, such as reading/writing images, 8cropping, finding the bounding box of a color and diffing images. 9 10When numpy is present, image_util_numpy_impl is used for the implementation of 11this interface. The old bitmap implementation (image_util_bitmap_impl) is used 12as a fallback when numpy is not present.""" 13 14import base64 15 16from telemetry.internal.util import external_modules 17 18np = external_modules.ImportOptionalModule('numpy') 19 20if np is None: 21 from telemetry.internal.image_processing import image_util_bitmap_impl 22 impl = image_util_bitmap_impl 23else: 24 from telemetry.internal.image_processing import image_util_numpy_impl 25 impl = image_util_numpy_impl 26 27 28def Channels(image): 29 """Number of color channels in the image.""" 30 return impl.Channels(image) 31 32def Width(image): 33 """Width of the image.""" 34 return impl.Width(image) 35 36def Height(image): 37 """Height of the image.""" 38 return impl.Height(image) 39 40def Pixels(image): 41 """Flat RGB pixel array of the image.""" 42 return impl.Pixels(image) 43 44def GetPixelColor(image, x, y): 45 """Returns a RgbaColor for the pixel at (x, y).""" 46 return impl.GetPixelColor(image, x, y) 47 48def WritePngFile(image, path): 49 """Write an image to a PNG file. 50 51 Args: 52 image: an image object. 53 path: The path to the PNG file. Must end in 'png' or an 54 AssertionError will be raised.""" 55 assert path.endswith('png') 56 return impl.WritePngFile(image, path) 57 58def FromRGBPixels(width, height, pixels, bpp=3): 59 """Create an image from an array of rgb pixels. 60 61 Ignores alpha channel if present. 62 63 Args: 64 width, height: int, the width and height of the image. 65 pixels: The flat array of pixels in the form of [r,g,b[,a],r,g,b[,a],...] 66 bpp: 3 for RGB, 4 for RGBA.""" 67 return impl.FromRGBPixels(width, height, pixels, bpp) 68 69def FromPng(png_data): 70 """Create an image from raw PNG data.""" 71 return impl.FromPng(png_data) 72 73def FromPngFile(path): 74 """Create an image from a PNG file. 75 76 Args: 77 path: The path to the PNG file.""" 78 return impl.FromPngFile(path) 79 80def FromBase64Png(base64_png): 81 """Create an image from raw PNG data encoded in base64.""" 82 return FromPng(base64.b64decode(base64_png)) 83 84def AreEqual(image1, image2, tolerance=0, likely_equal=True): 85 """Determines whether two images are identical within a given tolerance. 86 Setting likely_equal to False enables short-circuit equality testing, which 87 is about 2-3x slower for equal images, but can be image height times faster 88 if the images are not equal.""" 89 return impl.AreEqual(image1, image2, tolerance, likely_equal) 90 91def Diff(image1, image2): 92 """Returns a new image that represents the difference between this image 93 and another image.""" 94 return impl.Diff(image1, image2) 95 96def GetBoundingBox(image, color, tolerance=0): 97 """Finds the minimum box surrounding all occurrences of bgr |color|. 98 99 Ignores the alpha channel. 100 101 Args: 102 color: RbgaColor, bounding box color. 103 tolerance: int, per-channel tolerance for the bounding box color. 104 105 Returns: 106 (top, left, width, height), match_count""" 107 return impl.GetBoundingBox(image, color, tolerance) 108 109def Crop(image, left, top, width, height): 110 """Crops the current image down to the specified box.""" 111 return impl.Crop(image, left, top, width, height) 112 113def GetColorHistogram(image, ignore_color=None, tolerance=0): 114 """Computes a histogram of the pixel colors in this image. 115 Args: 116 ignore_color: An RgbaColor to exclude from the bucket counts. 117 tolerance: A tolerance for the ignore_color. 118 119 Returns: 120 A ColorHistogram namedtuple with 256 integers in each field: r, g, and b.""" 121 return impl.GetColorHistogram(image, ignore_color, tolerance) 122