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