2009-09-01 58 views
26

我已經厭倦了每次換我的iPhone應用程序的用戶界面時都會拍攝新的截圖。我希望能夠運行一個腳本/程序/無論在模擬器上加載我的二進制文件,然後做一些截圖。iPhone模擬器上的自動屏幕截圖?

該解決方案可以使用任何語言......對我無關緊要。

謝謝!

+2

我想聽到從設備上做到這一點的答案。 – 2009-09-01 04:51:17

回答

24

使用iPhone SDK 4,您可以自動執行GUI測試,並且可以爲您拍攝屏幕截圖。

基本上,你寫一個JavaScript腳本,然後儀器(使用自動化模板)可以在設備上運行它來測試UI,並且可以記錄數據,截圖等,並且如果有什麼東西被破壞也可以提醒。

我找不到它的參考指南,但在SDK參考庫中搜索UIA*類(如UIAElement)。

還有裏面的iPhone模擬器從WWDC demoing這個視頻,會話306

+1

以下是Apple的參考文檔:https:/ /developer.apple.com/library/mac/#documentation/DeveloperTools/Conceptual/InstrumentsUserGuide/Built-InInstruments/Built-InInstruments.html#//apple_ref/doc/uid/TP40004652-CH6-SW75 – 2011-12-13 20:34:26

6

私人UIGetScreenImage(void) API可用於捕獲屏幕的內容:

CGImageRef UIGetScreenImage(); 
void SaveScreenImage(NSString *path) 
{ 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
    CGImageRef cgImage = UIGetScreenImage(); 
    void *imageBytes = NULL; 
    if (cgImage == NULL) { 
     CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB(); 
     imageBytes = malloc(320 * 480 * 4); 
     CGContextRef context = CGBitmapContextCreate(imageBytes, 320, 480, 8, 320 * 4, colorspace, kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Big); 
     CGColorSpaceRelease(colorspace); 
     for (UIWindow *window in [[UIApplication sharedApplication] windows]) { 
      CGRect bounds = [window bounds]; 
      CALayer *layer = [window layer]; 
      CGContextSaveGState(context); 
      if ([layer contentsAreFlipped]) { 
       CGContextTranslateCTM(context, 0.0f, bounds.size.height); 
       CGContextScaleCTM(context, 1.0f, -1.0f); 
      } 
      [layer renderInContext:(CGContextRef)context]; 
      CGContextRestoreGState(context); 
     } 
     cgImage = CGBitmapContextCreateImage(context); 
     CGContextRelease(context); 
    } 
    NSData *pngData = UIImagePNGRepresentation([UIImage imageWithCGImage:cgImage]); 
    CGImageRelease(cgImage); 
    if (imageBytes) 
     free(imageBytes); 
    [pngData writeToFile:path atomically:YES]; 
    [pool release]; 
} 

一定要給它一個#ifdef內,因此不會出現在發佈版本。

+0

我無法讓方法UIGetScreenImage工作。 – 2009-09-10 15:15:08

+0

錯誤是什麼? – rpetrich 2009-09-11 05:23:58

+0

似乎UIGetScreenImage不再適用於模擬器:((最後我試着在2.x上)我已經更新了代碼以包含手動屏幕捕捉的基礎知識......它似乎在縱向窗口中工作得很好,如果你改進它,請更新我的答案:) – rpetrich 2009-09-11 06:54:57

12

我有同樣的願望。我希望能夠保存我的應用程序中幾個屏幕的屏幕截圖,而無需進行所有手動工作。我還沒到,但我已經開始了。

這個想法是尾部/var/log/system.log,從NSLog語句的輸出去。我將輸出輸出到一個python程序。 python程序讀取stdin中的所有行,當行匹配特定模式時,它會調用screencapture。

NSLog(@"screenshot mainmenu.png"); 

這將導致每次調用時都會創建一個名爲「XX。mainmenu YY.png」的屏幕截圖。 XX是自程序啓動以來屏幕截圖的編號。 YY是「mainmenu」屏幕截圖的編號。

我甚至增加了一些不必要的功能:

NSLog(@"screenshot -once mainmenu.png"); 

這隻會保存 「XX mainmenu.png。」 一次。

NSLog(@"screenshot -T 4 mainmenu.png"); 

這將使屏幕截圖延遲4秒後。

運行與正確的記錄應用後,可能已創建具有以下名稱的截屏:

00. SplashScreen.png 
01. MainMenu 01.png 
03. StartLevel 01.png 
04. GameOver 01.png 
05. MainMenu 02.png 

試試看:

  1. 一些的NSLog語句添加到您的代碼

  2. $ tail -f -n0 /var/log/system.log | ./grab.py

  3. 在模擬器

  4. 玩弄你的應用程序開始你的iPhone應用程序

  5. 看看截圖顯示了在您啓動grab.py程序

搶。潘岳:

#!/usr/bin/python 

import re 
import os 
from collections import defaultdict 

def screenshot(filename, select_window=False, delay_s=0): 
    flags = [] 
    if select_window: 
     flags.append('-w') 
    if delay_s: 
     flags.append('-T %d' % delay_s) 
    command_line = 'screencapture %s "%s"' % (' '.join(flags), filename) 
    #print command_line 
    os.system(command_line) 

def handle_line(line, count=defaultdict(int)): 
    params = parse_line(line) 
    if params: 
     filebase, fileextension, once, delay_s = params 
     if once and count[filebase] == 1: 
      print 'Skipping taking %s screenshot, already done once' % filebase 
     else: 
      count[filebase] += 1 
      number = count[filebase] 
      count[None] += 1 
      global_count = count[None] 
      file_count_string = (' %02d' % number) if not once else '' 

      filename = '%02d. %s%s.%s' % (global_count, filebase, file_count_string, fileextension) 
      print 'Taking screenshot: %s%s' % (filename, '' if delay_s == 0 else (' in %d seconds' % delay_s)) 
      screenshot(filename, select_window=False, delay_s=delay_s) 

def parse_line(line): 
    expression = r'.*screenshot\s*(?P<once>-once)?\s*(-delay\s*(?P<delay_s>\d+))?\s*(?P<filebase>\w+)?.?(?P<fileextension>\w+)?' 
    m = re.match(expression, line) 
    if m: 
     params = m.groupdict() 
     #print params 
     filebase = params['filebase'] or 'screenshot' 
     fileextension = params['fileextension'] or 'png' 
     once = params['once'] is not None 
     delay_s = int(params['delay_s'] or 0) 
     return filebase, fileextension, once, delay_s 
    else: 
     #print 'Ignore: %s' % line 
     return None 

def main(): 
    try: 
     while True: 
      handle_line(raw_input()) 
    except (EOFError, KeyboardInterrupt): 
     pass 

if __name__ == '__main__': 
    main() 

與此版本的問題:

如果你想只取iPhone模擬器窗口的截圖,你必須點擊iPhone模擬器窗口每截圖。 screencapture拒絕捕獲單個窗口,除非您願意與它交互,這是命令行工具的一個奇怪的設計決策。

更新:現在iPhone模擬器裁切器(在http://www.curioustimes.de/iphonesimulatorcropper/index.html)從命令行工作。因此,不要使用內置的screencapture,而應該下載並使用它。所以現在這個過程是完全自動的。

+2

這種技術的一個主要問題是,它需要僱用人員屏幕才能工作。我在沒有外部監視器的情況下在15英寸的MBP上進行了開發,並且此工具無法捕獲iPad大小的屏幕截圖。有關如何在沒有更大屏幕的情況下自動執行此操作的任何建議? – radven 2010-12-20 18:32:02

7

,有一個「複製屏幕」菜單項。當您按住Control鍵時,它會取代編輯菜單中的複製菜單項。 按鍵是Ctrl-Cmd-C 一個簡單的AppleScript可以複製一個ScreenShot並保存它。喜歡的東西(它的工作對我來說,即使是哈克):

tell application "iPhone Simulator" to activate 
tell application "System Events" 
    keystroke "c" using {command down, control down} 
end tell 
tell application "Preview" to activate 
tell application "System Events" 
    keystroke "n" using {command down} 
    keystroke "w" using {command down} 
    delay 1 
    keystroke return 
    delay 1 
    keystroke "File Name" 
    keystroke return 
end tell 

如果你不明白這一點,請評論...

0

您也可以使用一些屏幕捕獲應用程序在模擬器的屏幕上捕捉視頻。

我使用的應用程序很多。

我甚至用它來發送呈現應用程序的客戶端視頻......

相關問題