mirror of
https://github.com/processing/processing4.git
synced 2026-01-29 19:31:16 +01:00
remove quicktime video library
This commit is contained in:
@@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/processing-core"/>
|
||||
<classpathentry kind="lib" path="QTJava.zip"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
||||
@@ -1,17 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>processing-video</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -1,268 +0,0 @@
|
||||
#Wed Nov 04 22:32:11 EST 2009
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
|
||||
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
|
||||
org.eclipse.jdt.core.compiler.compliance=1.5
|
||||
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
|
||||
org.eclipse.jdt.core.compiler.debug.localVariable=generate
|
||||
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.source=1.5
|
||||
org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=18
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_assignment=0
|
||||
org.eclipse.jdt.core.formatter.alignment_for_binary_expression=18
|
||||
org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=82
|
||||
org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
|
||||
org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=18
|
||||
org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=18
|
||||
org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
|
||||
org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_after_package=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_field=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_method=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_package=0
|
||||
org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
|
||||
org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false
|
||||
org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false
|
||||
org.eclipse.jdt.core.formatter.comment.format_block_comments=true
|
||||
org.eclipse.jdt.core.formatter.comment.format_header=false
|
||||
org.eclipse.jdt.core.formatter.comment.format_html=true
|
||||
org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
|
||||
org.eclipse.jdt.core.formatter.comment.format_line_comments=true
|
||||
org.eclipse.jdt.core.formatter.comment.format_source_code=true
|
||||
org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true
|
||||
org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
|
||||
org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
|
||||
org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert
|
||||
org.eclipse.jdt.core.formatter.comment.line_length=80
|
||||
org.eclipse.jdt.core.formatter.compact_else_if=true
|
||||
org.eclipse.jdt.core.formatter.continuation_indentation=2
|
||||
org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
|
||||
org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
|
||||
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
|
||||
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
|
||||
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
|
||||
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
|
||||
org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
|
||||
org.eclipse.jdt.core.formatter.indent_empty_lines=false
|
||||
org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
|
||||
org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
|
||||
org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
|
||||
org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false
|
||||
org.eclipse.jdt.core.formatter.indentation.size=2
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_member=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
|
||||
org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
|
||||
org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
|
||||
org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false
|
||||
org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
|
||||
org.eclipse.jdt.core.formatter.lineSplit=80
|
||||
org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
|
||||
org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
|
||||
org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
|
||||
org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
|
||||
org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
|
||||
org.eclipse.jdt.core.formatter.tabulation.char=space
|
||||
org.eclipse.jdt.core.formatter.tabulation.size=2
|
||||
org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
|
||||
org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
|
||||
@@ -1,4 +0,0 @@
|
||||
#Tue Sep 30 10:42:04 EDT 2008
|
||||
eclipse.preferences.version=1
|
||||
formatter_profile=_two spaces no tabs
|
||||
formatter_settings_version=11
|
||||
@@ -1,26 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<project name="Processing Video Library" default="build">
|
||||
|
||||
<target name="clean" description="Clean the build directories">
|
||||
<delete dir="bin" />
|
||||
<delete file="library/video.jar" />
|
||||
</target>
|
||||
|
||||
<target name="compile" description="Compile sources">
|
||||
<condition property="core-built">
|
||||
<available file="../../../core/core.jar" />
|
||||
</condition>
|
||||
<fail unless="core-built" message="Please build the core library first and make sure it sits in ../../../core/core.jar" />
|
||||
|
||||
<mkdir dir="bin" />
|
||||
<javac target="1.5"
|
||||
srcdir="src" destdir="bin"
|
||||
encoding="UTF-8"
|
||||
includeAntRuntime="false"
|
||||
classpath="../../../core/core.jar; QTJava.zip" />
|
||||
</target>
|
||||
|
||||
<target name="build" depends="compile" description="Build video library">
|
||||
<jar basedir="bin" destfile="library/video.jar" />
|
||||
</target>
|
||||
</project>
|
||||
@@ -1,134 +0,0 @@
|
||||
/**
|
||||
* ASCII Video
|
||||
* by Ben Fry.
|
||||
*
|
||||
* Text characters have been used to represent images since the earliest computers.
|
||||
* This sketch is a simple homage that re-interprets live video as ASCII text.
|
||||
* See the keyPressed function for more options, like changing the font size.
|
||||
*/
|
||||
|
||||
import processing.video.*;
|
||||
|
||||
Capture video;
|
||||
boolean cheatScreen;
|
||||
|
||||
// All ASCII characters, sorted according to their visual density
|
||||
String letterOrder =
|
||||
" .`-_':,;^=+/\"|)\\<>)iv%xclrs{*}I?!][1taeo7zjLu" +
|
||||
"nT#JCwfy325Fp6mqSghVd4EgXPGZbYkOA&8U$@KHDBWNMR0Q";
|
||||
char[] letters;
|
||||
|
||||
float[] bright;
|
||||
char[] chars;
|
||||
|
||||
PFont font;
|
||||
float fontSize = 1.5;
|
||||
|
||||
|
||||
public void setup() {
|
||||
size(640, 480, P2D);
|
||||
// Or run full screen, more fun! Use with Sketch -> Present
|
||||
//size(screen.width, screen.height, OPENGL);
|
||||
|
||||
// Uses the default video input, see the reference if this causes an error
|
||||
video = new Capture(this, 80, 60, 15);
|
||||
int count = video.width * video.height;
|
||||
|
||||
font = loadFont("UniversLTStd-Light-48.vlw");
|
||||
|
||||
// for the 256 levels of brightness, distribute the letters across
|
||||
// the an array of 256 elements to use for the lookup
|
||||
letters = new char[256];
|
||||
for (int i = 0; i < 256; i++) {
|
||||
int index = int(map(i, 0, 256, 0, letterOrder.length()));
|
||||
letters[i] = letterOrder.charAt(index);
|
||||
}
|
||||
|
||||
// current characters for each position in the video
|
||||
chars = new char[count];
|
||||
|
||||
// current brightness for each point
|
||||
bright = new float[count];
|
||||
for (int i = 0; i < count; i++) {
|
||||
// set each brightness at the midpoint to start
|
||||
bright[i] = 128;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void captureEvent(Capture c) {
|
||||
c.read();
|
||||
}
|
||||
|
||||
|
||||
void draw() {
|
||||
background(0);
|
||||
|
||||
pushMatrix();
|
||||
|
||||
float hgap = width / float(video.width);
|
||||
float vgap = height / float(video.height);
|
||||
|
||||
scale(max(hgap, vgap) * fontSize);
|
||||
textFont(font, fontSize);
|
||||
|
||||
int index = 0;
|
||||
for (int y = 1; y < video.height; y++) {
|
||||
|
||||
// Move down for next line
|
||||
translate(0, 1.0 / fontSize);
|
||||
|
||||
pushMatrix();
|
||||
for (int x = 0; x < video.width; x++) {
|
||||
int pixelColor = video.pixels[index];
|
||||
// Faster method of calculating r, g, b than red(), green(), blue()
|
||||
int r = (pixelColor >> 16) & 0xff;
|
||||
int g = (pixelColor >> 8) & 0xff;
|
||||
int b = pixelColor & 0xff;
|
||||
|
||||
// Another option would be to properly calculate brightness as luminance:
|
||||
// luminance = 0.3*red + 0.59*green + 0.11*blue
|
||||
// Or you could instead red + green + blue, and make the the values[] array
|
||||
// 256*3 elements long instead of just 256.
|
||||
int pixelBright = max(r, g, b);
|
||||
|
||||
// The 0.1 value is used to damp the changes so that letters flicker less
|
||||
float diff = pixelBright - bright[index];
|
||||
bright[index] += diff * 0.1;
|
||||
|
||||
fill(pixelColor);
|
||||
int num = int(bright[index]);
|
||||
text(letters[num], 0, 0);
|
||||
|
||||
// Move to the next pixel
|
||||
index++;
|
||||
|
||||
// Move over for next character
|
||||
translate(1.0 / fontSize, 0);
|
||||
}
|
||||
popMatrix();
|
||||
}
|
||||
popMatrix();
|
||||
|
||||
if (cheatScreen) {
|
||||
//image(video, 0, height - video.height);
|
||||
// set() is faster than image() when drawing untransformed images
|
||||
set(0, height - video.height, video);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handle key presses:
|
||||
* 'c' toggles the cheat screen that shows the original image in the corner
|
||||
* 'g' grabs an image and saves the frame to a tiff image
|
||||
* 'f' and 'F' increase and decrease the font size
|
||||
*/
|
||||
public void keyPressed() {
|
||||
switch (key) {
|
||||
case 'g': saveFrame(); break;
|
||||
case 'c': cheatScreen = !cheatScreen; break;
|
||||
case 'f': fontSize *= 1.1; break;
|
||||
case 'F': fontSize *= 0.9; break;
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@@ -1,69 +0,0 @@
|
||||
/**
|
||||
* Background Subtraction
|
||||
* by Golan Levin.
|
||||
*
|
||||
* Detect the presence of people and objects in the frame using a simple
|
||||
* background-subtraction technique. To initialize the background, press a key.
|
||||
*/
|
||||
|
||||
|
||||
import processing.video.*;
|
||||
|
||||
int numPixels;
|
||||
int[] backgroundPixels;
|
||||
Capture video;
|
||||
|
||||
void setup() {
|
||||
// Change size to 320 x 240 if too slow at 640 x 480
|
||||
size(640, 480, P2D);
|
||||
|
||||
video = new Capture(this, width, height, 24);
|
||||
numPixels = video.width * video.height;
|
||||
// Create array to store the background image
|
||||
backgroundPixels = new int[numPixels];
|
||||
// Make the pixels[] array available for direct manipulation
|
||||
loadPixels();
|
||||
}
|
||||
|
||||
void draw() {
|
||||
if (video.available()) {
|
||||
video.read(); // Read a new video frame
|
||||
video.loadPixels(); // Make the pixels of video available
|
||||
// Difference between the current frame and the stored background
|
||||
int presenceSum = 0;
|
||||
for (int i = 0; i < numPixels; i++) { // For each pixel in the video frame...
|
||||
// Fetch the current color in that location, and also the color
|
||||
// of the background in that spot
|
||||
color currColor = video.pixels[i];
|
||||
color bkgdColor = backgroundPixels[i];
|
||||
// Extract the red, green, and blue components of the current pixel’s color
|
||||
int currR = (currColor >> 16) & 0xFF;
|
||||
int currG = (currColor >> 8) & 0xFF;
|
||||
int currB = currColor & 0xFF;
|
||||
// Extract the red, green, and blue components of the background pixel’s color
|
||||
int bkgdR = (bkgdColor >> 16) & 0xFF;
|
||||
int bkgdG = (bkgdColor >> 8) & 0xFF;
|
||||
int bkgdB = bkgdColor & 0xFF;
|
||||
// Compute the difference of the red, green, and blue values
|
||||
int diffR = abs(currR - bkgdR);
|
||||
int diffG = abs(currG - bkgdG);
|
||||
int diffB = abs(currB - bkgdB);
|
||||
// Add these differences to the running tally
|
||||
presenceSum += diffR + diffG + diffB;
|
||||
// Render the difference image to the screen
|
||||
//pixels[i] = color(diffR, diffG, diffB);
|
||||
// The following line does the same thing much faster, but is more technical
|
||||
pixels[i] = 0xFF000000 | (diffR << 16) | (diffG << 8) | diffB;
|
||||
}
|
||||
updatePixels(); // Notify that the pixels[] array has changed
|
||||
println(presenceSum); // Print out the total amount of movement
|
||||
}
|
||||
}
|
||||
|
||||
// When a key is pressed, capture the background image into the backgroundPixels
|
||||
// buffer, by copying each of the current frame’s pixels into it.
|
||||
void keyPressed() {
|
||||
video.loadPixels();
|
||||
arraycopy(video.pixels, backgroundPixels);
|
||||
}
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
/**
|
||||
* Brightness Thresholding
|
||||
* by Golan Levin.
|
||||
*
|
||||
* Determines whether a test location (such as the cursor) is contained within
|
||||
* the silhouette of a dark object.
|
||||
*/
|
||||
|
||||
|
||||
import processing.video.*;
|
||||
|
||||
color black = color(0);
|
||||
color white = color(255);
|
||||
int numPixels;
|
||||
Capture video;
|
||||
|
||||
void setup() {
|
||||
size(640, 480); // Change size to 320 x 240 if too slow at 640 x 480
|
||||
strokeWeight(5);
|
||||
// Uses the default video input, see the reference if this causes an error
|
||||
video = new Capture(this, width, height, 24);
|
||||
numPixels = video.width * video.height;
|
||||
noCursor();
|
||||
smooth();
|
||||
}
|
||||
|
||||
void draw() {
|
||||
if (video.available()) {
|
||||
video.read();
|
||||
video.loadPixels();
|
||||
int threshold = 127; // Set the threshold value
|
||||
float pixelBrightness; // Declare variable to store a pixel's color
|
||||
// Turn each pixel in the video frame black or white depending on its brightness
|
||||
loadPixels();
|
||||
for (int i = 0; i < numPixels; i++) {
|
||||
pixelBrightness = brightness(video.pixels[i]);
|
||||
if (pixelBrightness > threshold) { // If the pixel is brighter than the
|
||||
pixels[i] = white; // threshold value, make it white
|
||||
}
|
||||
else { // Otherwise,
|
||||
pixels[i] = black; // make it black
|
||||
}
|
||||
}
|
||||
updatePixels();
|
||||
// Test a location to see where it is contained. Fetch the pixel at the test
|
||||
// location (the cursor), and compute its brightness
|
||||
int testValue = get(mouseX, mouseY);
|
||||
float testBrightness = brightness(testValue);
|
||||
if (testBrightness > threshold) { // If the test location is brighter than
|
||||
fill(black); // the threshold set the fill to black
|
||||
}
|
||||
else { // Otherwise,
|
||||
fill(white); // set the fill to white
|
||||
}
|
||||
ellipse(mouseX, mouseY, 20, 20);
|
||||
}
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
/**
|
||||
* Brightness Tracking
|
||||
* by Golan Levin.
|
||||
*
|
||||
* Tracks the brightest pixel in a live video signal.
|
||||
*/
|
||||
|
||||
|
||||
import processing.video.*;
|
||||
|
||||
Capture video;
|
||||
|
||||
void setup() {
|
||||
size(640, 480); // Change size to 320 x 240 if too slow at 640 x 480
|
||||
// Uses the default video input, see the reference if this causes an error
|
||||
video = new Capture(this, width, height, 30);
|
||||
noStroke();
|
||||
smooth();
|
||||
}
|
||||
|
||||
void draw() {
|
||||
if (video.available()) {
|
||||
video.read();
|
||||
image(video, 0, 0, width, height); // Draw the webcam video onto the screen
|
||||
int brightestX = 0; // X-coordinate of the brightest video pixel
|
||||
int brightestY = 0; // Y-coordinate of the brightest video pixel
|
||||
float brightestValue = 0; // Brightness of the brightest video pixel
|
||||
// Search for the brightest pixel: For each row of pixels in the video image and
|
||||
// for each pixel in the yth row, compute each pixel's index in the video
|
||||
video.loadPixels();
|
||||
int index = 0;
|
||||
for (int y = 0; y < video.height; y++) {
|
||||
for (int x = 0; x < video.width; x++) {
|
||||
// Get the color stored in the pixel
|
||||
int pixelValue = video.pixels[index];
|
||||
// Determine the brightness of the pixel
|
||||
float pixelBrightness = brightness(pixelValue);
|
||||
// If that value is brighter than any previous, then store the
|
||||
// brightness of that pixel, as well as its (x,y) location
|
||||
if (pixelBrightness > brightestValue) {
|
||||
brightestValue = pixelBrightness;
|
||||
brightestY = y;
|
||||
brightestX = x;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
}
|
||||
// Draw a large, yellow circle at the brightest pixel
|
||||
fill(255, 204, 0, 128);
|
||||
ellipse(brightestX, brightestY, 200, 200);
|
||||
}
|
||||
}
|
||||
@@ -1,145 +0,0 @@
|
||||
/**
|
||||
* Color Sorting
|
||||
* by Ben Fry.
|
||||
*
|
||||
* Example that sorts all colors from the incoming video
|
||||
* and arranges them into vertical bars.
|
||||
*/
|
||||
|
||||
|
||||
import processing.video.*;
|
||||
|
||||
Capture video;
|
||||
boolean cheatScreen;
|
||||
|
||||
Tuple[] captureColors;
|
||||
Tuple[] drawColors;
|
||||
int[] bright;
|
||||
|
||||
// How many pixels to skip in either direction
|
||||
int increment = 5;
|
||||
|
||||
|
||||
void setup() {
|
||||
size(800, 600, P3D);
|
||||
|
||||
noCursor();
|
||||
// Uses the default video input, see the reference if this causes an error
|
||||
video = new Capture(this, 80, 60, 15);
|
||||
|
||||
int count = (video.width * video.height) / (increment * increment);
|
||||
bright = new int[count];
|
||||
captureColors = new Tuple[count];
|
||||
drawColors = new Tuple[count];
|
||||
for (int i = 0; i < count; i++) {
|
||||
captureColors[i] = new Tuple();
|
||||
drawColors[i] = new Tuple(0.5, 0.5, 0.5);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void draw() {
|
||||
if (video.available()) {
|
||||
video.read();
|
||||
|
||||
background(0);
|
||||
noStroke();
|
||||
|
||||
int index = 0;
|
||||
for (int j = 0; j < video.height; j += increment) {
|
||||
for (int i = 0; i < video.width; i += increment) {
|
||||
int pixelColor = video.pixels[j*video.width + i];
|
||||
|
||||
int r = (pixelColor >> 16) & 0xff;
|
||||
int g = (pixelColor >> 8) & 0xff;
|
||||
int b = pixelColor & 0xff;
|
||||
|
||||
// Technically would be sqrt of the following, but no need to do
|
||||
// sqrt before comparing the elements since we're only ordering
|
||||
bright[index] = r*r + g*g + b*b;
|
||||
captureColors[index].set(r, g, b);
|
||||
|
||||
index++;
|
||||
}
|
||||
}
|
||||
sort(index, bright, captureColors);
|
||||
|
||||
beginShape(QUAD_STRIP);
|
||||
for (int i = 0; i < index; i++) {
|
||||
drawColors[i].target(captureColors[i], 0.1);
|
||||
drawColors[i].phil();
|
||||
|
||||
float x = map(i, 0, index, 0, width);
|
||||
vertex(x, 0);
|
||||
vertex(x, height);
|
||||
}
|
||||
endShape();
|
||||
|
||||
if (cheatScreen) {
|
||||
//image(video, 0, height - video.height);
|
||||
// Faster method of displaying pixels array on screen
|
||||
set(0, height - video.height, video);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void keyPressed() {
|
||||
if (key == 'g') {
|
||||
saveFrame();
|
||||
}
|
||||
else if (key == 'c') {
|
||||
cheatScreen = !cheatScreen;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Functions to handle sorting the color data
|
||||
|
||||
|
||||
void sort(int length, int[] a, Tuple[] stuff) {
|
||||
sortSub(a, stuff, 0, length - 1);
|
||||
}
|
||||
|
||||
|
||||
void sortSwap(int[] a, Tuple[] stuff, int i, int j) {
|
||||
int T = a[i];
|
||||
a[i] = a[j];
|
||||
a[j] = T;
|
||||
|
||||
Tuple v = stuff[i];
|
||||
stuff[i] = stuff[j];
|
||||
stuff[j] = v;
|
||||
}
|
||||
|
||||
|
||||
void sortSub(int[] a, Tuple[] stuff, int lo0, int hi0) {
|
||||
int lo = lo0;
|
||||
int hi = hi0;
|
||||
int mid;
|
||||
|
||||
if (hi0 > lo0) {
|
||||
mid = a[(lo0 + hi0) / 2];
|
||||
|
||||
while (lo <= hi) {
|
||||
while ((lo < hi0) && (a[lo] < mid)) {
|
||||
++lo;
|
||||
}
|
||||
while ((hi > lo0) && (a[hi] > mid)) {
|
||||
--hi;
|
||||
}
|
||||
if (lo <= hi) {
|
||||
sortSwap(a, stuff, lo, hi);
|
||||
++lo;
|
||||
--hi;
|
||||
}
|
||||
}
|
||||
|
||||
if (lo0 < hi)
|
||||
sortSub(a, stuff, lo0, hi);
|
||||
|
||||
if (lo < hi0)
|
||||
sortSub(a, stuff, lo, hi0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
// Simple vector class that holds an x,y,z position.
|
||||
|
||||
class Tuple {
|
||||
float x, y, z;
|
||||
|
||||
Tuple() { }
|
||||
|
||||
Tuple(float x, float y, float z) {
|
||||
set(x, y, z);
|
||||
}
|
||||
|
||||
void set(float x, float y, float z) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
void target(Tuple another, float amount) {
|
||||
float amount1 = 1.0 - amount;
|
||||
x = x*amount1 + another.x*amount;
|
||||
y = y*amount1 + another.y*amount;
|
||||
z = z*amount1 + another.z*amount;
|
||||
}
|
||||
|
||||
void phil() {
|
||||
fill(x, y, z);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
/**
|
||||
* Drawing Movie.
|
||||
*
|
||||
* Makes a QuickTime movie of a line drawn by the mouse. Press
|
||||
* the spacebar to finish and save the movie.
|
||||
*/
|
||||
|
||||
import processing.video.*;
|
||||
|
||||
MovieMaker mm;
|
||||
|
||||
void setup() {
|
||||
size(320, 240);
|
||||
|
||||
// Save uncompressed, at 15 frames per second
|
||||
mm = new MovieMaker(this, width, height, "drawing.mov");
|
||||
|
||||
// Or, set specific compression and frame rate options
|
||||
//mm = new MovieMaker(this, width, height, "drawing.mov", 30,
|
||||
// MovieMaker.ANIMATION, MovieMaker.HIGH);
|
||||
|
||||
background(160, 32, 32);
|
||||
}
|
||||
|
||||
|
||||
void draw() {
|
||||
stroke(7, 146, 168);
|
||||
strokeWeight(4);
|
||||
|
||||
// Draw if mouse is pressed
|
||||
if (mousePressed && pmouseX != 0 && mouseY != 0) {
|
||||
line(pmouseX, pmouseY, mouseX, mouseY);
|
||||
}
|
||||
|
||||
// Add window's pixels to movie
|
||||
mm.addFrame();
|
||||
}
|
||||
|
||||
|
||||
void keyPressed() {
|
||||
if (key == ' ') {
|
||||
// Finish the movie if space bar is pressed
|
||||
mm.finish();
|
||||
// Quit running the sketch once the file is written
|
||||
exit();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
/**
|
||||
* Frame Differencing
|
||||
* by Golan Levin.
|
||||
*
|
||||
* Quantify the amount of movement in the video frame using frame-differencing.
|
||||
*/
|
||||
|
||||
|
||||
import processing.video.*;
|
||||
|
||||
int numPixels;
|
||||
int[] previousFrame;
|
||||
Capture video;
|
||||
|
||||
void setup() {
|
||||
size(640, 480); // Change size to 320 x 240 if too slow at 640 x 480
|
||||
// Uses the default video input, see the reference if this causes an error
|
||||
video = new Capture(this, width, height, 24);
|
||||
numPixels = video.width * video.height;
|
||||
// Create an array to store the previously captured frame
|
||||
previousFrame = new int[numPixels];
|
||||
loadPixels();
|
||||
}
|
||||
|
||||
void draw() {
|
||||
if (video.available()) {
|
||||
// When using video to manipulate the screen, use video.available() and
|
||||
// video.read() inside the draw() method so that it's safe to draw to the screen
|
||||
video.read(); // Read the new frame from the camera
|
||||
video.loadPixels(); // Make its pixels[] array available
|
||||
|
||||
int movementSum = 0; // Amount of movement in the frame
|
||||
for (int i = 0; i < numPixels; i++) { // For each pixel in the video frame...
|
||||
color currColor = video.pixels[i];
|
||||
color prevColor = previousFrame[i];
|
||||
// Extract the red, green, and blue components from current pixel
|
||||
int currR = (currColor >> 16) & 0xFF; // Like red(), but faster
|
||||
int currG = (currColor >> 8) & 0xFF;
|
||||
int currB = currColor & 0xFF;
|
||||
// Extract red, green, and blue components from previous pixel
|
||||
int prevR = (prevColor >> 16) & 0xFF;
|
||||
int prevG = (prevColor >> 8) & 0xFF;
|
||||
int prevB = prevColor & 0xFF;
|
||||
// Compute the difference of the red, green, and blue values
|
||||
int diffR = abs(currR - prevR);
|
||||
int diffG = abs(currG - prevG);
|
||||
int diffB = abs(currB - prevB);
|
||||
// Add these differences to the running tally
|
||||
movementSum += diffR + diffG + diffB;
|
||||
// Render the difference image to the screen
|
||||
pixels[i] = color(diffR, diffG, diffB);
|
||||
// The following line is much faster, but more confusing to read
|
||||
//pixels[i] = 0xff000000 | (diffR << 16) | (diffG << 8) | diffB;
|
||||
// Save the current color into the 'previous' buffer
|
||||
previousFrame[i] = currColor;
|
||||
}
|
||||
// To prevent flicker from frames that are all black (no movement),
|
||||
// only update the screen if the image has changed.
|
||||
if (movementSum > 0) {
|
||||
updatePixels();
|
||||
println(movementSum); // Print the total amount of movement to the console
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
/**
|
||||
* Framingham
|
||||
* by Ben Fry.
|
||||
*
|
||||
* Show subsequent frames from video input as a grid. Also fun with movie files.
|
||||
*/
|
||||
|
||||
|
||||
import processing.video.*;
|
||||
|
||||
Capture video;
|
||||
int column;
|
||||
int columnCount;
|
||||
int lastRow;
|
||||
|
||||
// Buffer used to move all the pixels up
|
||||
int[] scoot;
|
||||
|
||||
|
||||
void setup() {
|
||||
size(640, 480, P2D);
|
||||
|
||||
// Uses the default video input, see the reference if this causes an error
|
||||
video = new Capture(this, 32, 24);
|
||||
// Also try with other video sizes
|
||||
|
||||
column = 0;
|
||||
columnCount = width / video.width;
|
||||
int rowCount = height / video.height;
|
||||
lastRow = rowCount - 1;
|
||||
|
||||
scoot = new int[lastRow*video.height * width];
|
||||
background(0);
|
||||
}
|
||||
|
||||
|
||||
void draw() {
|
||||
// By using video.available, only the frame rate need be set inside setup()
|
||||
if (video.available()) {
|
||||
video.read();
|
||||
set(video.width*column, video.height*lastRow, video);
|
||||
column++;
|
||||
if (column == columnCount) {
|
||||
loadPixels();
|
||||
|
||||
// Scoot everybody up one row
|
||||
arraycopy(pixels, video.height*width, scoot, 0, scoot.length);
|
||||
arraycopy(scoot, 0, pixels, 0, scoot.length);
|
||||
|
||||
// Set the moved row to black
|
||||
for (int i = scoot.length; i < width*height; i++) {
|
||||
pixels[i] = #000000;
|
||||
}
|
||||
column = 0;
|
||||
updatePixels();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
/**
|
||||
* Getting Started with Capture.
|
||||
*
|
||||
* Reading and displaying an image from an attached Capture device.
|
||||
*/
|
||||
|
||||
import processing.video.*;
|
||||
|
||||
Capture cam;
|
||||
|
||||
void setup() {
|
||||
size(640, 480);
|
||||
|
||||
// If no device is specified, will just use the default.
|
||||
cam = new Capture(this, 320, 240);
|
||||
|
||||
// To use another device (i.e. if the default device causes an error),
|
||||
// list all available capture devices to the console to find your camera.
|
||||
//String[] devices = Capture.list();
|
||||
//println(devices);
|
||||
|
||||
// Change devices[0] to the proper index for your camera.
|
||||
//cam = new Capture(this, width, height, devices[0]);
|
||||
|
||||
// Opens the settings page for this capture device.
|
||||
//camera.settings();
|
||||
}
|
||||
|
||||
|
||||
void draw() {
|
||||
if (cam.available() == true) {
|
||||
cam.read();
|
||||
image(cam, 160, 100);
|
||||
// The following does the same, and is faster when just drawing the image
|
||||
// without any additional resizing, transformations, or tint.
|
||||
//set(160, 100, cam);
|
||||
}
|
||||
}
|
||||
@@ -1,207 +0,0 @@
|
||||
/**
|
||||
* HSV Space
|
||||
* by Ben Fry.
|
||||
*
|
||||
* Arrange the pixels from live video into the HSV Color Cone.
|
||||
*/
|
||||
|
||||
import java.awt.Color;
|
||||
|
||||
import processing.opengl.*;
|
||||
import processing.video.*;
|
||||
|
||||
Capture video;
|
||||
int count;
|
||||
boolean cheatScreen = true;
|
||||
|
||||
static final float BOX_SIZE = 0.75;
|
||||
static final float CONE_HEIGHT = 1.2;
|
||||
static final float MAX_RADIUS = 10;
|
||||
static final float ROT_INCREMENT = 3.0;
|
||||
static final float TRANS_INCREMENT = 1;
|
||||
static final float STEP_AMOUNT = 0.1;
|
||||
|
||||
Tuple[] farbe;
|
||||
Tuple[] trans;
|
||||
|
||||
float[] hsb = new float[3];
|
||||
|
||||
float leftRightAngle;
|
||||
float upDownAngle;
|
||||
float fwdBackTrans;
|
||||
float upDownTrans;
|
||||
float leftRightTrans;
|
||||
boolean motion;
|
||||
|
||||
boolean blobby = false;
|
||||
|
||||
|
||||
void setup() {
|
||||
size(640, 480, P3D);
|
||||
//size(screen.width, screen.height, OPENGL);
|
||||
|
||||
video = new Capture(this, 40, 30, 15);
|
||||
count = video.width * video.height;
|
||||
|
||||
sphereDetail(60);
|
||||
|
||||
upDownTrans = 0;
|
||||
leftRightTrans = 0;
|
||||
motion = false;
|
||||
|
||||
leftRightAngle = 101.501297;
|
||||
upDownAngle = -180.098694;
|
||||
fwdBackTrans = 14.800003;
|
||||
|
||||
farbe = new Tuple[count];
|
||||
trans = new Tuple[count];
|
||||
for (int i = 0; i < count; i++) {
|
||||
farbe[i] = new Tuple();
|
||||
trans[i] = new Tuple();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void draw() {
|
||||
background(0);
|
||||
|
||||
if (!blobby) lights();
|
||||
|
||||
pushMatrix();
|
||||
translate(width/2, height/2);
|
||||
scale(min(width, height) / 10.0);
|
||||
|
||||
translate(0, 0, -20 + fwdBackTrans);
|
||||
rotateY(radians(36 + leftRightAngle)); //, 0, 1, 0);
|
||||
rotateX(radians(-228 + upDownAngle)); //, 1, 0, 0);
|
||||
|
||||
if (blobby) {
|
||||
stroke(0.35, 0.35, 0.25, 0.15);
|
||||
wireCone(MAX_RADIUS, MAX_RADIUS * CONE_HEIGHT, 18, 18);
|
||||
}
|
||||
else {
|
||||
stroke(0.35, 0.35, 0.25, 0.25);
|
||||
wireCone(MAX_RADIUS, MAX_RADIUS * CONE_HEIGHT, 180, 18);
|
||||
}
|
||||
|
||||
noStroke();
|
||||
for (int i = 0; i < count; i++) {
|
||||
int pixelColor = video.pixels[i];
|
||||
int r = (pixelColor >> 16) & 0xff;
|
||||
int g = (pixelColor >> 8) & 0xff;
|
||||
int b = pixelColor & 0xff;
|
||||
Color.RGBtoHSB(r, g, b, hsb);
|
||||
|
||||
float radius = hsb[1] * hsb[2];
|
||||
float angle = hsb[0] * 360.0 * DEG_TO_RAD;
|
||||
float nx = MAX_RADIUS * radius * cos(angle);
|
||||
float ny = MAX_RADIUS * radius * sin(angle);
|
||||
float nz = hsb[2] * MAX_RADIUS * CONE_HEIGHT;
|
||||
|
||||
trans[i].set(trans[i].x - (trans[i].x - nx)*STEP_AMOUNT,
|
||||
trans[i].y - (trans[i].y - ny)*STEP_AMOUNT,
|
||||
trans[i].z - (trans[i].z - nz)*STEP_AMOUNT);
|
||||
|
||||
farbe[i].set(farbe[i].x - (farbe[i].x - r)*STEP_AMOUNT,
|
||||
farbe[i].y - (farbe[i].y - g)*STEP_AMOUNT,
|
||||
farbe[i].z - (farbe[i].z - b)*STEP_AMOUNT);
|
||||
|
||||
pushMatrix();
|
||||
farbe[i].phil();
|
||||
trans[i].tran();
|
||||
|
||||
rotate(radians(45), 1, 1, 0);
|
||||
if (blobby) {
|
||||
sphere(BOX_SIZE * 2); //, 20, 20);
|
||||
} else {
|
||||
box(BOX_SIZE);
|
||||
}
|
||||
|
||||
popMatrix();
|
||||
}
|
||||
popMatrix();
|
||||
|
||||
if (motion) {
|
||||
upDownAngle--;
|
||||
leftRightAngle--;
|
||||
}
|
||||
|
||||
if (cheatScreen) {
|
||||
image(video, 0, height - video.height);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void captureEvent(Capture c) {
|
||||
c.read();
|
||||
c.loadPixels();
|
||||
}
|
||||
|
||||
|
||||
void keyPressed() {
|
||||
switch (key) {
|
||||
case 'g':
|
||||
saveFrame();
|
||||
break;
|
||||
case 'c':
|
||||
cheatScreen = !cheatScreen;
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
motion = !motion;
|
||||
break;
|
||||
case '=':
|
||||
fwdBackTrans += TRANS_INCREMENT;
|
||||
break;
|
||||
case '-':
|
||||
fwdBackTrans -= TRANS_INCREMENT;
|
||||
break;
|
||||
case 'b':
|
||||
blobby = !blobby;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void mouseDragged() {
|
||||
float dX, dY;
|
||||
|
||||
switch (mouseButton) {
|
||||
case LEFT: // left right up down
|
||||
dX = pmouseX - mouseX;
|
||||
dY = pmouseY - mouseY;
|
||||
leftRightAngle -= dX * 0.2;
|
||||
upDownAngle += dY * 0.4;
|
||||
break;
|
||||
|
||||
case CENTER:
|
||||
dX = pmouseX - mouseX;
|
||||
dY = pmouseY - mouseY;
|
||||
leftRightTrans -= TRANS_INCREMENT * dX;
|
||||
upDownTrans -= TRANS_INCREMENT * dY;
|
||||
break;
|
||||
|
||||
case RIGHT: // in and out
|
||||
dY = (float) (pmouseY - mouseY);
|
||||
fwdBackTrans -= TRANS_INCREMENT * dY;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void wireCone(float radius, float height, int stepX, int stepY) {
|
||||
int steps = 10;
|
||||
stroke(40);
|
||||
for (int i = 0; i < steps; i++) {
|
||||
float angle = map(i, 0, steps, 0, TWO_PI);
|
||||
float x = radius * cos(angle);
|
||||
float y = radius * sin(angle);
|
||||
line(x, y, height, 0, 0, 0);
|
||||
}
|
||||
noFill();
|
||||
pushMatrix();
|
||||
translate(0, 0, height);
|
||||
ellipseMode(CENTER_RADIUS);
|
||||
ellipse(0, 0, radius, radius);
|
||||
popMatrix();
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
// Simple vector class that holds an x,y,z position.
|
||||
|
||||
class Tuple {
|
||||
float x, y, z;
|
||||
|
||||
Tuple() { }
|
||||
|
||||
Tuple(float x, float y, float z) {
|
||||
set(x, y, z);
|
||||
}
|
||||
|
||||
void set(float x, float y, float z) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
void target(Tuple another, float amount) {
|
||||
float amount1 = 1.0 - amount;
|
||||
x = x*amount1 + another.x*amount;
|
||||
y = y*amount1 + another.y*amount;
|
||||
z = z*amount1 + another.z*amount;
|
||||
}
|
||||
|
||||
void phil() {
|
||||
fill(x, y, z);
|
||||
}
|
||||
|
||||
void tran() {
|
||||
translate(x, y, z);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
/**
|
||||
* Live Pocky
|
||||
* by Ben Fry.
|
||||
*
|
||||
* Unwrap each frame of live video into a single line of pixels.
|
||||
*/
|
||||
|
||||
import processing.video.*;
|
||||
|
||||
Capture video;
|
||||
int count;
|
||||
int writeRow;
|
||||
int maxRows;
|
||||
int topRow;
|
||||
int buffer[];
|
||||
|
||||
|
||||
void setup() {
|
||||
size(600, 400);
|
||||
|
||||
// Uses the default video input, see the reference if this causes an error
|
||||
video = new Capture(this, 30, 20);
|
||||
|
||||
maxRows = height * 2;
|
||||
buffer = new int[width * maxRows];
|
||||
writeRow = height - 1;
|
||||
topRow = 0;
|
||||
|
||||
//frameRate(10);
|
||||
background(0);
|
||||
loadPixels();
|
||||
}
|
||||
|
||||
|
||||
void draw() {
|
||||
for (int y = 0; y < height; y++) {
|
||||
int row = (topRow + y) % maxRows;
|
||||
arraycopy(buffer, row * width, g.pixels, y*width, width);
|
||||
}
|
||||
updatePixels();
|
||||
}
|
||||
|
||||
|
||||
void captureEvent(Capture c) {
|
||||
c.read();
|
||||
c.loadPixels();
|
||||
arraycopy(c.pixels, 0, buffer, writeRow * width, width);
|
||||
writeRow++;
|
||||
if (writeRow == maxRows) {
|
||||
writeRow = 0;
|
||||
}
|
||||
topRow++;
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
/**
|
||||
* Loop.
|
||||
*
|
||||
* Move the cursor across the screen to draw.
|
||||
* Shows how to load and play a QuickTime movie file.
|
||||
*/
|
||||
|
||||
import processing.video.*;
|
||||
|
||||
Movie myMovie;
|
||||
|
||||
void setup() {
|
||||
size(640, 480, P2D);
|
||||
background(0);
|
||||
// Load and play the video in a loop
|
||||
myMovie = new Movie(this, "station.mov");
|
||||
myMovie.loop();
|
||||
}
|
||||
|
||||
void movieEvent(Movie myMovie) {
|
||||
myMovie.read();
|
||||
}
|
||||
|
||||
void draw() {
|
||||
tint(255, 20);
|
||||
image(myMovie, mouseX-myMovie.width/2, mouseY-myMovie.height/2);
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
/**
|
||||
* Mirror
|
||||
* by Daniel Shiffman.
|
||||
*
|
||||
* Each pixel from the video source is drawn as a rectangle with rotation based on brightness.
|
||||
*/
|
||||
|
||||
|
||||
import processing.video.*;
|
||||
|
||||
// Size of each cell in the grid
|
||||
int cellSize = 20;
|
||||
// Number of columns and rows in our system
|
||||
int cols, rows;
|
||||
// Variable for capture device
|
||||
Capture video;
|
||||
|
||||
|
||||
void setup() {
|
||||
size(640, 480, P2D);
|
||||
frameRate(30);
|
||||
cols = width / cellSize;
|
||||
rows = height / cellSize;
|
||||
colorMode(RGB, 255, 255, 255, 100);
|
||||
|
||||
// Uses the default video input, see the reference if this causes an error
|
||||
video = new Capture(this, width, height, 12);
|
||||
|
||||
background(0);
|
||||
}
|
||||
|
||||
|
||||
void draw() {
|
||||
if (video.available()) {
|
||||
video.read();
|
||||
video.loadPixels();
|
||||
|
||||
// Not bothering to clear background
|
||||
// background(0);
|
||||
|
||||
// Begin loop for columns
|
||||
for (int i = 0; i < cols; i++) {
|
||||
// Begin loop for rows
|
||||
for (int j = 0; j < rows; j++) {
|
||||
|
||||
// Where are we, pixel-wise?
|
||||
int x = i*cellSize;
|
||||
int y = j*cellSize;
|
||||
int loc = (video.width - x - 1) + y*video.width; // Reversing x to mirror the image
|
||||
|
||||
float r = red(video.pixels[loc]);
|
||||
float g = green(video.pixels[loc]);
|
||||
float b = blue(video.pixels[loc]);
|
||||
// Make a new color with an alpha component
|
||||
color c = color(r, g, b, 75);
|
||||
|
||||
// Code for drawing a single rect
|
||||
// Using translate in order for rotation to work properly
|
||||
pushMatrix();
|
||||
translate(x+cellSize/2, y+cellSize/2);
|
||||
// Rotation formula based on brightness
|
||||
rotate((2 * PI * brightness(c) / 255.0));
|
||||
rectMode(CENTER);
|
||||
fill(c);
|
||||
noStroke();
|
||||
// Rects are larger than the cell for some overlap
|
||||
rect(0, 0, cellSize+6, cellSize+6);
|
||||
popMatrix();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
/**
|
||||
* Mirror 2
|
||||
* by Daniel Shiffman.
|
||||
*
|
||||
* Each pixel from the video source is drawn as a rectangle with size based on brightness.
|
||||
*/
|
||||
|
||||
import processing.video.*;
|
||||
|
||||
// Size of each cell in the grid
|
||||
int cellSize = 15;
|
||||
// Number of columns and rows in our system
|
||||
int cols, rows;
|
||||
// Variable for capture device
|
||||
Capture video;
|
||||
|
||||
|
||||
void setup() {
|
||||
size(630, 480, P2D);
|
||||
//set up columns and rows
|
||||
cols = width / cellSize;
|
||||
rows = height / cellSize;
|
||||
colorMode(RGB, 255, 255, 255, 100);
|
||||
rectMode(CENTER);
|
||||
|
||||
// Uses the default video input, see the reference if this causes an error
|
||||
video = new Capture(this, width, height, 15);
|
||||
|
||||
background(0);
|
||||
}
|
||||
|
||||
|
||||
void draw() {
|
||||
if (video.available()) {
|
||||
video.read();
|
||||
video.loadPixels();
|
||||
|
||||
background(0, 0, 255);
|
||||
|
||||
// Begin loop for columns
|
||||
for (int i = 0; i < cols;i++) {
|
||||
// Begin loop for rows
|
||||
for (int j = 0; j < rows;j++) {
|
||||
|
||||
// Where are we, pixel-wise?
|
||||
int x = i * cellSize;
|
||||
int y = j * cellSize;
|
||||
int loc = (video.width - x - 1) + y*video.width; // Reversing x to mirror the image
|
||||
|
||||
// Each rect is colored white with a size determined by brightness
|
||||
color c = video.pixels[loc];
|
||||
float sz = (brightness(c) / 255.0) * cellSize;
|
||||
fill(255);
|
||||
noStroke();
|
||||
rect(x + cellSize/2, y + cellSize/2, sz, sz);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
/**
|
||||
* Pixelate
|
||||
* by Hernando Barragan.
|
||||
*
|
||||
* Load a QuickTime file and display the video signal
|
||||
* using rectangles as pixels by reading the values stored
|
||||
* in the current video frame pixels array.
|
||||
*/
|
||||
|
||||
|
||||
import processing.video.*;
|
||||
|
||||
int numPixels;
|
||||
int blockSize = 10;
|
||||
Movie myMovie;
|
||||
color myMovieColors[];
|
||||
|
||||
void setup() {
|
||||
size(640, 480, P2D);
|
||||
noStroke();
|
||||
background(0);
|
||||
myMovie = new Movie(this, "station.mov");
|
||||
myMovie.loop();
|
||||
numPixels = width / blockSize;
|
||||
myMovieColors = new color[numPixels * numPixels];
|
||||
}
|
||||
|
||||
// Read new values from movie
|
||||
void movieEvent(Movie m) {
|
||||
m.read();
|
||||
m.loadPixels();
|
||||
|
||||
for (int j = 0; j < numPixels; j++) {
|
||||
for (int i = 0; i < numPixels; i++) {
|
||||
myMovieColors[j*numPixels + i] = m.get(i, j);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Display values from movie
|
||||
void draw() {
|
||||
for (int j = 0; j < numPixels; j++) {
|
||||
for (int i = 0; i < numPixels; i++) {
|
||||
fill(myMovieColors[j*numPixels + i]);
|
||||
rect(i*blockSize, j*blockSize, blockSize-1, blockSize-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
/**
|
||||
* Radial Pocky
|
||||
* by Ben Fry.
|
||||
*
|
||||
* Unwrap each frame of live video into a single line of pixels along a circle
|
||||
*/
|
||||
|
||||
|
||||
import processing.video.*;
|
||||
|
||||
Capture video;
|
||||
int videoCount;
|
||||
int currentAngle;
|
||||
int pixelCount;
|
||||
int angleCount = 200; // how many divisions
|
||||
|
||||
int radii[];
|
||||
int angles[];
|
||||
|
||||
void setup() {
|
||||
// size must be set to video.width*video.height*2 in both directions
|
||||
size(960, 540);
|
||||
|
||||
// Uses the default video input, see the reference if this causes an error
|
||||
video = new Capture(this, 24, 16);
|
||||
videoCount = video.width * video.height;
|
||||
|
||||
pixelCount = width*height;
|
||||
int centerX = width / 2;
|
||||
int centerY = height / 2;
|
||||
radii = new int[pixelCount];
|
||||
angles = new int[pixelCount];
|
||||
|
||||
int offset = 0;
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (int x = 0; x < width; x++) {
|
||||
int dx = centerX - x;
|
||||
int dy = centerY - y;
|
||||
|
||||
float angle = atan2(dy, dx);
|
||||
if (angle < 0) angle += TWO_PI;
|
||||
angles[offset] = (int) (angleCount * (angle / TWO_PI));
|
||||
|
||||
int radius = (int) mag(dx, dy);
|
||||
if (radius >= videoCount) {
|
||||
radius = -1;
|
||||
angles[offset] = -1;
|
||||
}
|
||||
radii[offset] = radius;
|
||||
|
||||
offset++;
|
||||
}
|
||||
}
|
||||
background(0);
|
||||
}
|
||||
|
||||
|
||||
void draw() {
|
||||
if (video.available()) {
|
||||
video.read();
|
||||
video.loadPixels();
|
||||
|
||||
loadPixels();
|
||||
for (int i = 0; i < pixelCount; i++) {
|
||||
if (angles[i] == currentAngle) {
|
||||
pixels[i] = video.pixels[radii[i]];
|
||||
}
|
||||
}
|
||||
updatePixels();
|
||||
|
||||
currentAngle++;
|
||||
if (currentAngle == angleCount) currentAngle = 0;
|
||||
}
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
/**
|
||||
* Simple Real-Time Slit-Scan Program.
|
||||
* By Golan Levin.
|
||||
*
|
||||
* This demonstration depends on the canvas height being equal
|
||||
* to the video capture height. If you would prefer otherwise,
|
||||
* consider using the image copy() function rather than the
|
||||
* direct pixel-accessing approach I have used here.
|
||||
*
|
||||
* Created December 2006.
|
||||
* Updated June 2007 by fry.
|
||||
*/
|
||||
import processing.video.*;
|
||||
|
||||
Capture video;
|
||||
|
||||
int videoSliceX;
|
||||
int drawPositionX;
|
||||
|
||||
|
||||
void setup() {
|
||||
size(600, 240, P2D);
|
||||
|
||||
// Uses the default video input, see the reference if this causes an error
|
||||
video = new Capture(this, 320, 240, 30);
|
||||
|
||||
videoSliceX = video.width / 2;
|
||||
drawPositionX = width - 1;
|
||||
background(0);
|
||||
}
|
||||
|
||||
|
||||
void draw() {
|
||||
if (video.available()) {
|
||||
video.read();
|
||||
video.loadPixels();
|
||||
|
||||
// Copy a column of pixels from the middle of the video
|
||||
// To a location moving slowly across the canvas.
|
||||
loadPixels();
|
||||
for (int y = 0; y < video.height; y++){
|
||||
int setPixelIndex = y*width + drawPositionX;
|
||||
int getPixelIndex = y*video.width + videoSliceX;
|
||||
pixels[setPixelIndex] = video.pixels[getPixelIndex];
|
||||
}
|
||||
updatePixels();
|
||||
|
||||
drawPositionX--;
|
||||
// Wrap the position back to the beginning if necessary.
|
||||
if (drawPositionX < 0) {
|
||||
drawPositionX = width - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
video.jar
|
||||
@@ -1 +0,0 @@
|
||||
name = Video
|
||||
@@ -1,549 +0,0 @@
|
||||
/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
|
||||
|
||||
/*
|
||||
Part of the Processing project - http://processing.org
|
||||
|
||||
Copyright (c) 2004-09 Ben Fry and Casey Reas
|
||||
The previous version of this code was developed by Hernando Barragan
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General
|
||||
Public License along with this library; if not, write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
package processing.video;
|
||||
|
||||
import processing.core.*;
|
||||
|
||||
import java.lang.reflect.*;
|
||||
|
||||
import quicktime.*;
|
||||
import quicktime.qd.*;
|
||||
import quicktime.std.*;
|
||||
import quicktime.std.sg.*;
|
||||
import quicktime.util.RawEncodedImage;
|
||||
|
||||
|
||||
/**
|
||||
* Watchin' shit on the telly.
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public class Capture extends PImage implements Runnable {
|
||||
|
||||
// there are more, but these are all we'll provide for now
|
||||
// The useful ref page for <a href="http://developer.apple.com/documentation/Java/Reference/1.4.1/Java141API_QTJ/constant-values.html">quicktime constants</a>
|
||||
static public final int COMPOSITE = StdQTConstants.compositeIn; // 0
|
||||
static public final int SVIDEO = StdQTConstants.sVideoIn; // 1
|
||||
static public final int COMPONENT = StdQTConstants.rgbComponentIn; // 2
|
||||
static public final int TUNER = StdQTConstants.tvTunerIn; // 6
|
||||
|
||||
static public final int NTSC = StdQTConstants.ntscIn;
|
||||
static public final int PAL = StdQTConstants.palIn;
|
||||
static public final int SECAM = StdQTConstants.secamIn;
|
||||
|
||||
// no longer needed because parent field added to PImage
|
||||
//PApplet parent;
|
||||
|
||||
Method captureEventMethod;
|
||||
String name; // keep track for error messages (unused)
|
||||
Thread runner;
|
||||
|
||||
boolean available = false;
|
||||
|
||||
/** Temporary storage for the raw image
|
||||
data read directly from the capture device */
|
||||
public int data[];
|
||||
|
||||
public int dataWidth;
|
||||
public int dataHeight;
|
||||
public int dataRowBytes;
|
||||
|
||||
/** True if this image is currently being cropped */
|
||||
public boolean crop;
|
||||
|
||||
public int cropX;
|
||||
public int cropY;
|
||||
public int cropW;
|
||||
public int cropH;
|
||||
|
||||
public int frameRate;
|
||||
|
||||
public RawEncodedImage raw;
|
||||
public SequenceGrabber capture;
|
||||
|
||||
/** the guy who's doing all the work */
|
||||
public SGVideoChannel channel;
|
||||
|
||||
/** boundary of image at the requested size */
|
||||
protected QDRect qdrect;
|
||||
|
||||
/*
|
||||
static {
|
||||
try {
|
||||
QTSession.open();
|
||||
} catch (QTException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
// this doesn't appear to do jack
|
||||
QTRuntimeException.registerHandler(new QTRuntimeHandler() {
|
||||
public void exceptionOccurred(QTRuntimeException e,
|
||||
Object obj, String s, boolean flag) {
|
||||
System.err.println("Problem inside Capture");
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
public Capture(PApplet parent, int requestWidth, int requestHeight) {
|
||||
this(parent, requestWidth, requestHeight, null, 30);
|
||||
}
|
||||
|
||||
public Capture(PApplet parent, int reqWidth, int reqHeight, int frameRate) {
|
||||
this(parent, reqWidth, reqHeight, null, frameRate);
|
||||
}
|
||||
|
||||
public Capture(PApplet parent, int reqWidth, int reqHeight, String name) {
|
||||
this(parent, reqWidth, reqHeight, name, 30);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* If 'name' is null or the empty string, it won't set a specific
|
||||
* device, which means that QuickTime will use that last device
|
||||
* used by a QuickTime application.
|
||||
* <P/>
|
||||
* Unfortunately, Apple's QuickTime API uses the name to select devices,
|
||||
* and in some cases there might be cameras with the same name on a machine.
|
||||
* If you ask for a camera of the same name in sequence, you might see if it
|
||||
* just does the right thing and grabs each separate camera in succession.
|
||||
* If that doesn't work, you might try calling settings() which will
|
||||
* bring up the prompt where you can select a capture device.
|
||||
* <P/>
|
||||
* If the following function:
|
||||
* <PRE>public void captureEvent(Capture c)</PRE>
|
||||
* is defined in the host PApplet, then it will be called every
|
||||
* time a new frame is available from the capture device.
|
||||
*/
|
||||
public Capture(final PApplet parent,
|
||||
final int requestWidth, final int requestHeight,
|
||||
final String name, final int frameRate) {
|
||||
// Running on EDT because of weird hang on OS X
|
||||
// http://dev.processing.org/bugs/show_bug.cgi?id=882
|
||||
// QTSession.open() is hanging, not sure why, but it seems to prefer
|
||||
// being run from the EDT. Not sure if that's a mistaken expectation in
|
||||
// QTJava (we hadn't had trouble in the past because we did everything
|
||||
// on the EDT) or if something broken in more recent QTJ. Or (maybe most
|
||||
// likely) we're simply hitting some other threading strangeness, and
|
||||
// using invokeLater() isolates us from that. Which is a nice way of
|
||||
// saying that it's a hack.
|
||||
//SwingUtilities.invokeLater(new Runnable() {
|
||||
// public void run() {
|
||||
init(parent, requestWidth, requestHeight, name, frameRate);
|
||||
//}
|
||||
//});
|
||||
}
|
||||
|
||||
|
||||
public void init(PApplet parent, int requestWidth, int requestHeight,
|
||||
String name, int frameRate) {
|
||||
this.parent = parent;
|
||||
this.name = name;
|
||||
this.frameRate = frameRate;
|
||||
|
||||
try {
|
||||
QTSession.open();
|
||||
} catch (QTException e) {
|
||||
e.printStackTrace(System.out);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
qdrect = new QDRect(requestWidth, requestHeight);
|
||||
// workaround for bug with the intel macs
|
||||
QDGraphics qdgraphics = null; //new QDGraphics(qdrect);
|
||||
if (quicktime.util.EndianOrder.isNativeLittleEndian()) {
|
||||
qdgraphics = new QDGraphics(QDConstants.k32BGRAPixelFormat, qdrect);
|
||||
} else {
|
||||
qdgraphics = new QDGraphics(QDGraphics.kDefaultPixelFormat, qdrect);
|
||||
}
|
||||
|
||||
capture = new SequenceGrabber();
|
||||
capture.setGWorld(qdgraphics, null);
|
||||
|
||||
channel = new SGVideoChannel(capture);
|
||||
channel.setBounds(qdrect);
|
||||
channel.setUsage(2); // what is this usage number?
|
||||
capture.startPreview(); // maybe this comes later?
|
||||
|
||||
PixMap pixmap = qdgraphics.getPixMap();
|
||||
raw = pixmap.getPixelData();
|
||||
|
||||
/*
|
||||
if (name == null) {
|
||||
channel.settingsDialog();
|
||||
|
||||
} else if (name.length() > 0) {
|
||||
channel.setDevice(name);
|
||||
}
|
||||
*/
|
||||
if ((name != null) && (name.length() > 0)) {
|
||||
channel.setDevice(name);
|
||||
}
|
||||
|
||||
dataRowBytes = raw.getRowBytes();
|
||||
dataWidth = dataRowBytes / 4;
|
||||
dataHeight = raw.getSize() / dataRowBytes;
|
||||
|
||||
if (dataWidth != requestWidth) {
|
||||
crop = true;
|
||||
cropX = 0;
|
||||
cropY = 0;
|
||||
cropW = requestWidth;
|
||||
cropH = requestHeight;
|
||||
}
|
||||
// initialize my PImage self
|
||||
super.init(requestWidth, requestHeight, RGB);
|
||||
|
||||
parent.registerDispose(this);
|
||||
|
||||
try {
|
||||
captureEventMethod =
|
||||
parent.getClass().getMethod("captureEvent",
|
||||
new Class[] { Capture.class });
|
||||
} catch (Exception e) {
|
||||
// no such method, or an error.. which is fine, just ignore
|
||||
}
|
||||
|
||||
runner = new Thread(this);
|
||||
runner.start();
|
||||
|
||||
} catch (QTException qte) {
|
||||
//} catch (StdQTException qte) {
|
||||
//qte.printStackTrace();
|
||||
|
||||
int errorCode = qte.errorCode();
|
||||
if (errorCode == Errors.couldntGetRequiredComponent) {
|
||||
// this can happen when the capture device isn't available
|
||||
// or wasn't shut down properly
|
||||
parent.die("No capture could be found, " +
|
||||
"or the VDIG is not installed correctly.", qte);
|
||||
} else {
|
||||
parent.die("Error while setting up Capture", qte);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
parent.die("Error while setting up Capture", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* True if a frame is ready to be read.
|
||||
* <PRE>
|
||||
* // put this somewhere inside draw
|
||||
* if (capture.available()) capture.read();
|
||||
* </PRE>
|
||||
* Alternatively, you can use captureEvent(Capture c) to notify you
|
||||
* whenever available() is set to true. In which case, things might
|
||||
* look like this:
|
||||
* <PRE>
|
||||
* public void captureEvent(Capture c) {
|
||||
* c.read();
|
||||
* // do something exciting now that c has been updated
|
||||
* }
|
||||
* </PRE>
|
||||
*/
|
||||
public boolean available() {
|
||||
return available;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the video to crop from its original.
|
||||
* <P>
|
||||
* It seems common that captures add lines to the top or bottom
|
||||
* of an image, so this can be useful for removing them.
|
||||
* Internally, the pixel buffer size returned from QuickTime is
|
||||
* often a different size than requested, so crop will be set
|
||||
* more often than not.
|
||||
*/
|
||||
public void crop(int x, int y, int w, int h) {
|
||||
/*
|
||||
if (imageMode == CORNERS) {
|
||||
w -= x; // w was actually x2
|
||||
h -= y; // h was actually y2
|
||||
}
|
||||
*/
|
||||
|
||||
crop = true;
|
||||
cropX = Math.max(0, x);
|
||||
cropY = Math.max(0, y);
|
||||
cropW = Math.min(w, dataWidth);
|
||||
cropH = Math.min(dataHeight, y + h) - cropY;
|
||||
|
||||
// if size has changed, re-init this image
|
||||
if ((cropW != width) || (cropH != height)) {
|
||||
init(w, h, RGB);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Remove the cropping (if any) of the image.
|
||||
* <P>
|
||||
* By default, cropping is often enabled to trim out black pixels.
|
||||
* But if you'd rather deal with them yourself (so as to avoid
|
||||
* an extra lag while the data is moved around) you can shut it off.
|
||||
*/
|
||||
public void noCrop() {
|
||||
crop = false;
|
||||
}
|
||||
|
||||
|
||||
public void read() {
|
||||
//try {
|
||||
//synchronized (capture) {
|
||||
loadPixels();
|
||||
synchronized (pixels) {
|
||||
//System.out.println("read1");
|
||||
if (crop) {
|
||||
//System.out.println("read2a");
|
||||
// f#$)(#$ing quicktime / jni is so g-d slow, calling copyToArray
|
||||
// for the invidual rows is literally 100x slower. instead, first
|
||||
// copy the entire buffer to a separate array (i didn't need that
|
||||
// memory anyway), and do an arraycopy for each row.
|
||||
if (data == null) {
|
||||
data = new int[dataWidth * dataHeight];
|
||||
}
|
||||
raw.copyToArray(0, data, 0, dataWidth * dataHeight);
|
||||
int sourceOffset = cropX + cropY*dataWidth;
|
||||
int destOffset = 0;
|
||||
for (int y = 0; y < cropH; y++) {
|
||||
System.arraycopy(data, sourceOffset, pixels, destOffset, cropW);
|
||||
sourceOffset += dataWidth;
|
||||
destOffset += width;
|
||||
}
|
||||
} else { // no crop, just copy directly
|
||||
//System.out.println("read2b");
|
||||
raw.copyToArray(0, pixels, 0, width * height);
|
||||
}
|
||||
//System.out.println("read3");
|
||||
|
||||
available = false;
|
||||
// mark this image as modified so that PGraphicsJava2D and
|
||||
// PGraphicsOpenGL will properly re-blit and draw this guy
|
||||
updatePixels();
|
||||
//System.out.println("read4");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void run() {
|
||||
while ((Thread.currentThread() == runner) && (capture != null)) {
|
||||
try {
|
||||
synchronized (capture) {
|
||||
capture.idle();
|
||||
//read();
|
||||
available = true;
|
||||
|
||||
if (captureEventMethod != null) {
|
||||
try {
|
||||
captureEventMethod.invoke(parent, new Object[] { this });
|
||||
} catch (Exception e) {
|
||||
System.err.println("Disabling captureEvent() for " + name +
|
||||
" because of an error.");
|
||||
e.printStackTrace();
|
||||
captureEventMethod = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} catch (QTException e) {
|
||||
errorMessage("run", e);
|
||||
}
|
||||
|
||||
try {
|
||||
Thread.sleep(1000 / frameRate);
|
||||
} catch (InterruptedException e) { }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the frameRate for how quickly new frames are read
|
||||
* from the capture device.
|
||||
*/
|
||||
public void frameRate(int iframeRate) {
|
||||
if (iframeRate <= 0) {
|
||||
System.err.println("Capture: ignoring bad frameRate of " +
|
||||
iframeRate + " fps.");
|
||||
return;
|
||||
}
|
||||
frameRate = iframeRate;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Called by applets to stop capturing video.
|
||||
*/
|
||||
public void stop() {
|
||||
if (capture != null) {
|
||||
try {
|
||||
capture.stop(); // stop the "preview"
|
||||
} catch (StdQTException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
capture = null;
|
||||
}
|
||||
runner = null; // unwind the thread
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Called by PApplet to shut down video so that QuickTime
|
||||
* can be used later by another applet.
|
||||
*/
|
||||
public void dispose() {
|
||||
stop();
|
||||
//System.out.println("calling dispose");
|
||||
// this is important so that the next app can do video
|
||||
QTSession.close();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* General error reporting, all corraled here just in case
|
||||
* I think of something slightly more intelligent to do.
|
||||
*/
|
||||
protected void errorMessage(String where, Exception e) {
|
||||
parent.die("Error inside Capture." + where + "()", e);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the format to ask for from the video digitizer:
|
||||
* TUNER, COMPOSITE, SVIDEO, or COMPONENT.
|
||||
* <P>
|
||||
* The constants are just aliases to the constants returned from
|
||||
* QuickTime's getInputFormat() function, so any valid constant from
|
||||
* that will work just fine.
|
||||
*/
|
||||
public void source(int which) {
|
||||
try {
|
||||
VideoDigitizer digitizer = channel.getDigitizerComponent();
|
||||
int count = digitizer.getNumberOfInputs();
|
||||
for (int i = 0; i < count; i++) {
|
||||
//System.out.println("format " + digitizer.getInputFormat(i));
|
||||
if (digitizer.getInputFormat(i) == which) {
|
||||
digitizer.setInput(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw new RuntimeException("The specified source() is not available.");
|
||||
|
||||
} catch (StdQTException e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException("Could not set the video input source.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the video format standard to use on the
|
||||
* video digitizer: NTSC, PAL, or SECAM.
|
||||
* <P>
|
||||
* The constants are just aliases to the constants used for
|
||||
* QuickTime's setInputStandard() function, so any valid
|
||||
* constant from that will work just fine.
|
||||
*/
|
||||
public void format(int which) {
|
||||
try {
|
||||
VideoDigitizer digitizer = channel.getDigitizerComponent();
|
||||
digitizer.setInputStandard(which);
|
||||
} catch (StdQTException e) {
|
||||
e.printStackTrace();
|
||||
//throw new RuntimeException("Could not set the video input format");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Show the settings dialog for this input device.
|
||||
*/
|
||||
public void settings() {
|
||||
try {
|
||||
// fix for crash here submitted by hansi (stop/startPreview lines)
|
||||
capture.stop();
|
||||
|
||||
// Whenever settingsDialog() is called, the boundries change,
|
||||
// causing the image to be cropped. Fix for Bug #366
|
||||
// http://dev.processing.org/bugs/show_bug.cgi?id=366
|
||||
channel.setBounds(qdrect);
|
||||
|
||||
// Open the settings dialog (throws an Exception if canceled)
|
||||
channel.settingsDialog();
|
||||
|
||||
} catch (StdQTException qte) {
|
||||
int errorCode = qte.errorCode();
|
||||
if (errorCode == Errors.userCanceledErr) {
|
||||
// User only canceled the settings dialog, continue as we were
|
||||
} else {
|
||||
qte.printStackTrace();
|
||||
throw new RuntimeException("Error inside Capture.settings()");
|
||||
}
|
||||
}
|
||||
try {
|
||||
// Start the preview again (unreachable if newly thrown exception)
|
||||
capture.startPreview();
|
||||
} catch (StdQTException qte) {
|
||||
qte.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a list of all available captures as a String array.
|
||||
* i.e. println(Capture.list()) will show you the goodies.
|
||||
*/
|
||||
static public String[] list() {
|
||||
try {
|
||||
QTSession.open();
|
||||
SequenceGrabber grabber = new SequenceGrabber();
|
||||
SGVideoChannel channel = new SGVideoChannel(grabber);
|
||||
|
||||
SGDeviceList deviceList = channel.getDeviceList(0); // flags is 0
|
||||
String listing[] = new String[deviceList.getCount()];
|
||||
for (int i = 0; i < deviceList.getCount(); i++) {
|
||||
listing[i] = deviceList.getDeviceName(i).getName();
|
||||
}
|
||||
// properly shut down the channel so the app can use it again
|
||||
grabber.disposeChannel(channel);
|
||||
QTSession.close();
|
||||
return listing;
|
||||
|
||||
} catch (QTException qte) {
|
||||
int errorCode = qte.errorCode();
|
||||
if (errorCode == Errors.couldntGetRequiredComponent) {
|
||||
throw new RuntimeException("Couldn't find any capture devices, " +
|
||||
"read the video reference for more info.");
|
||||
} else {
|
||||
qte.printStackTrace();
|
||||
throw new RuntimeException("Problem listing capture devices, " +
|
||||
"read the video reference for more info.");
|
||||
}
|
||||
}
|
||||
//return null;
|
||||
}
|
||||
}
|
||||
@@ -1,735 +0,0 @@
|
||||
/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
|
||||
|
||||
/*
|
||||
Part of the Processing project - http://processing.org
|
||||
|
||||
Copyright (c) 2004-07 Ben Fry and Casey Reas
|
||||
The previous version of this code was developed by Hernando Barragan
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General
|
||||
Public License along with this library; if not, write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
package processing.video;
|
||||
|
||||
import processing.core.*;
|
||||
|
||||
import java.io.*;
|
||||
import java.lang.reflect.*;
|
||||
|
||||
import quicktime.*;
|
||||
import quicktime.io.QTFile;
|
||||
import quicktime.qd.*;
|
||||
import quicktime.std.*;
|
||||
import quicktime.std.movies.media.DataRef;
|
||||
import quicktime.util.QTHandle;
|
||||
import quicktime.util.RawEncodedImage;
|
||||
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public class Movie extends PImage implements PConstants, Runnable {
|
||||
Method movieEventMethod;
|
||||
String filename;
|
||||
Thread runner;
|
||||
|
||||
PImage borderImage;
|
||||
boolean removeBorders = true;
|
||||
|
||||
boolean play;
|
||||
boolean repeat;
|
||||
boolean available;
|
||||
int fps;
|
||||
|
||||
/**
|
||||
* The QuickTime for Java "Movie" object, made public
|
||||
* in case anyone wants to play with it.
|
||||
*/
|
||||
public quicktime.std.movies.Movie movie;
|
||||
|
||||
QDRect movieRect;
|
||||
QDGraphics movieGraphics;
|
||||
boolean firstFrame = true;
|
||||
RawEncodedImage raw;
|
||||
|
||||
|
||||
/*
|
||||
static {
|
||||
try {
|
||||
//System.out.println("jlp = " + System.getProperty("java.library.path"));
|
||||
QTSession.open();
|
||||
} catch (QTException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
// shutting off for 0116, hoping for better exception handling
|
||||
QTRuntimeException.registerHandler(new QTRuntimeHandler() {
|
||||
public void exceptionOccurred(QTRuntimeException e,
|
||||
Object obj, String s, boolean flag) {
|
||||
System.err.println("Problem inside Movie");
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
public Movie(PApplet parent, String filename) {
|
||||
this(parent, filename, 30);
|
||||
}
|
||||
|
||||
|
||||
public Movie(final PApplet parent, final String filename, final int ifps) {
|
||||
// this creates a fake image so that the first time this
|
||||
// attempts to draw, something happens that's not an exception
|
||||
super(1, 1, RGB);
|
||||
|
||||
// http://dev.processing.org/bugs/show_bug.cgi?id=882
|
||||
//SwingUtilities.invokeLater(new Runnable() {
|
||||
//public void run() {
|
||||
init(parent, filename, ifps);
|
||||
//}
|
||||
//});
|
||||
}
|
||||
|
||||
|
||||
public void init(PApplet parent, String filename, int fps) {
|
||||
this.parent = parent;
|
||||
this.fps = fps;
|
||||
|
||||
try {
|
||||
QTSession.open();
|
||||
} catch (QTException e) {
|
||||
e.printStackTrace();
|
||||
return;
|
||||
}
|
||||
|
||||
// first check to see if this can be read locally from a file.
|
||||
// otherwise, will have to load the file into memory, which is
|
||||
// gonna make people unhappy who are trying to play back 50 MB
|
||||
// quicktime movies with a locally installed piece exported
|
||||
// as an application.
|
||||
try {
|
||||
try {
|
||||
// first try a local file using the dataPath. usually this will
|
||||
// work ok, but sometimes the dataPath is inside a jar file,
|
||||
// which is less fun, so this will crap out.
|
||||
File file = new File(parent.dataPath(filename));
|
||||
if (file.exists()) {
|
||||
movie = fromDataRef(new DataRef(new QTFile(file)));
|
||||
//init(parent, movie, ifps);
|
||||
//return;
|
||||
}
|
||||
} catch (Exception e) { } // ignored
|
||||
|
||||
// read from a folder local to the current working dir
|
||||
// called "data". presumably this might be the data folder,
|
||||
// though that should be caught above, if such a folder exists.
|
||||
/*
|
||||
if (movie == null) {
|
||||
try {
|
||||
File file = new File("data", filename);
|
||||
if (file.exists()) {
|
||||
movie = fromDataRef(new DataRef(new QTFile(file)));
|
||||
init(parent, movie, ifps);
|
||||
return;
|
||||
}
|
||||
} catch (QTException e2) { }
|
||||
}
|
||||
*/
|
||||
|
||||
// read from a file just hanging out in the local folder.
|
||||
// this might happen when the video library is used with some
|
||||
// other application, or the person enters a full path name
|
||||
if (movie == null) {
|
||||
try {
|
||||
File file = new File(filename);
|
||||
if (file.exists()) {
|
||||
movie = fromDataRef(new DataRef(new QTFile(file)));
|
||||
//init(parent, movie, ifps);
|
||||
//return;
|
||||
}
|
||||
} catch (QTException e1) { }
|
||||
}
|
||||
|
||||
} catch (SecurityException se) {
|
||||
// online, whups. catch the security exception out here rather than
|
||||
// doing it three times (or whatever) for each of the cases above.
|
||||
}
|
||||
|
||||
// if the movie can't be read from a local file, it has to be read
|
||||
// into a byte array and passed to qtjava. it's annoying that apple
|
||||
// doesn't have something in the api to read a movie from a friggin
|
||||
// InputStream, but oh well. it's their api.
|
||||
if (movie == null) {
|
||||
byte data[] = parent.loadBytes(filename);
|
||||
//int dot = filename.lastIndexOf(".");
|
||||
// grab the extension from the file, use mov if there is none
|
||||
//String extension = (dot == -1) ? "mov" :
|
||||
// filename.substring(dot + 1).toLowerCase();
|
||||
try {
|
||||
movie = fromDataRef(new DataRef(new QTHandle(data)));
|
||||
} catch (QTException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
URL url = null;
|
||||
this.filename = filename; // for error messages
|
||||
|
||||
if (filename.startsWith("http://")) {
|
||||
try {
|
||||
url = new URL(filename);
|
||||
DataRef urlRef = new DataRef(url.toExternalForm());
|
||||
movie = fromDataRef(urlRef);
|
||||
init(parent, movie, ifps);
|
||||
return;
|
||||
|
||||
} catch (QTException qte) {
|
||||
qte.printStackTrace();
|
||||
return;
|
||||
|
||||
} catch (MalformedURLException e) {
|
||||
e.printStackTrace();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// updated for new loading style of 0096
|
||||
ClassLoader cl = parent.getClass().getClassLoader();
|
||||
url = cl.getResource("data/" + filename);
|
||||
if (url != null) {
|
||||
init(parent, url, ifps);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
try {
|
||||
File file = new File(parent.dataPath(filename));
|
||||
if (file.exists()) {
|
||||
movie = fromDataRef(new DataRef(new QTFile(file)));
|
||||
init(parent, movie, ifps);
|
||||
return;
|
||||
}
|
||||
} catch (Exception e) { } // ignored
|
||||
|
||||
try {
|
||||
File file = new File("data", filename);
|
||||
if (file.exists()) {
|
||||
movie = fromDataRef(new DataRef(new QTFile(file)));
|
||||
init(parent, movie, ifps);
|
||||
return;
|
||||
}
|
||||
} catch (QTException e2) { }
|
||||
|
||||
try {
|
||||
File file = new File(filename);
|
||||
if (file.exists()) {
|
||||
movie = fromDataRef(new DataRef(new QTFile(file)));
|
||||
init(parent, movie, ifps);
|
||||
return;
|
||||
}
|
||||
} catch (QTException e1) { }
|
||||
|
||||
} catch (SecurityException se) { } // online, whups
|
||||
*/
|
||||
|
||||
if (movie == null) {
|
||||
parent.die("Could not find movie file " + filename, null);
|
||||
}
|
||||
|
||||
// we've got a valid movie! let's rock.
|
||||
try {
|
||||
// this is probably causing the 2 seconds of audio
|
||||
// disabled pre-preroll on 0126 because of security problems
|
||||
//movie.prePreroll(0, 1.0f);
|
||||
movie.preroll(0, 1.0f);
|
||||
|
||||
// this has a possibility of running forever..
|
||||
// should probably happen on the thread as well.
|
||||
while (movie.maxLoadedTimeInMovie() == 0) {
|
||||
movie.task(100);
|
||||
|
||||
// 0106: tried adding sleep time so this doesn't spin out of control
|
||||
// works fine but doesn't really help anything
|
||||
//try {
|
||||
//Thread.sleep(5);
|
||||
//} catch (InterruptedException e) { }
|
||||
}
|
||||
movie.setRate(1);
|
||||
//fps = ifps;
|
||||
|
||||
// register methods
|
||||
parent.registerDispose(this);
|
||||
|
||||
try {
|
||||
movieEventMethod =
|
||||
parent.getClass().getMethod("movieEvent",
|
||||
new Class[] { Movie.class });
|
||||
} catch (Exception e) {
|
||||
// no such method, or an error.. which is fine, just ignore
|
||||
}
|
||||
|
||||
// and now, make the magic happen
|
||||
runner = new Thread(this);
|
||||
runner.start();
|
||||
|
||||
} catch (QTException qte) {
|
||||
qte.printStackTrace();
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
public Movie(PApplet parent, URL url) {
|
||||
init(parent, url, 30);
|
||||
}
|
||||
|
||||
|
||||
public Movie(PApplet parent, URL url, int ifps) {
|
||||
init(parent, url, ifps);
|
||||
}
|
||||
|
||||
|
||||
public void init(PApplet parent, URL url, int ifps) {
|
||||
|
||||
String externalized = url.toExternalForm();
|
||||
System.out.println("externalized is " + externalized);
|
||||
|
||||
// qtjava likes file: urls to read file:/// not file:/
|
||||
// so this changes them when appropriate
|
||||
if (externalized.startsWith("file:/") &&
|
||||
!externalized.startsWith("file:///")) {
|
||||
externalized = "file:///" + url.getPath();
|
||||
}
|
||||
|
||||
// the url version is the only available that can take
|
||||
// an InputStream (indirectly) since it uses url syntax
|
||||
//DataRef urlRef = new DataRef(requestFile);
|
||||
try {
|
||||
System.out.println(url);
|
||||
System.out.println(externalized);
|
||||
DataRef urlRef = new DataRef(externalized);
|
||||
System.out.println(urlRef);
|
||||
|
||||
movie = fromDataRef(urlRef);
|
||||
init(parent, movie, ifps);
|
||||
|
||||
} catch (QTException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Why does this function have to be so bizarre? i love the huge
|
||||
* constants! i think they're neato. i feel like i'm coding for
|
||||
* think pascal on my mac plus! those were happier times.
|
||||
*/
|
||||
private quicktime.std.movies.Movie fromDataRef(DataRef ref)
|
||||
throws QTException {
|
||||
|
||||
return
|
||||
quicktime.std.movies.Movie.fromDataRef(ref,
|
||||
StdQTConstants4.newMovieAsyncOK |
|
||||
StdQTConstants.newMovieActive);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
public void init(PApplet parent,
|
||||
quicktime.std.movies.Movie movie, int ifps) {
|
||||
this.parent = parent;
|
||||
|
||||
try {
|
||||
// this is probably causing the 2 seconds of audio
|
||||
movie.prePreroll(0, 1.0f);
|
||||
movie.preroll(0, 1.0f);
|
||||
|
||||
// this has a possibility of running forever..
|
||||
// should probably happen on the thread as well.
|
||||
while (movie.maxLoadedTimeInMovie() == 0) {
|
||||
movie.task(100);
|
||||
|
||||
// 0106: tried adding sleep time so this doesn't spin out of control
|
||||
// works fine but doesn't really help anything
|
||||
//try {
|
||||
//Thread.sleep(5);
|
||||
//} catch (InterruptedException e) { }
|
||||
}
|
||||
movie.setRate(1);
|
||||
fps = ifps;
|
||||
|
||||
runner = new Thread(this);
|
||||
runner.start();
|
||||
|
||||
|
||||
// register methods
|
||||
|
||||
parent.registerDispose(this);
|
||||
|
||||
try {
|
||||
movieEventMethod =
|
||||
parent.getClass().getMethod("movieEvent",
|
||||
new Class[] { Movie.class });
|
||||
} catch (Exception e) {
|
||||
// no such method, or an error.. which is fine, just ignore
|
||||
}
|
||||
|
||||
} catch (QTException qte) {
|
||||
qte.printStackTrace();
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
public boolean available() {
|
||||
return available;
|
||||
}
|
||||
|
||||
|
||||
public void read() {
|
||||
try {
|
||||
if (firstFrame) {
|
||||
movieRect = movie.getBox();
|
||||
//movieGraphics = new QDGraphics(movieRect);
|
||||
if (quicktime.util.EndianOrder.isNativeLittleEndian()) {
|
||||
movieGraphics =
|
||||
new QDGraphics(QDConstants.k32BGRAPixelFormat, movieRect);
|
||||
} else {
|
||||
movieGraphics =
|
||||
new QDGraphics(QDGraphics.kDefaultPixelFormat, movieRect);
|
||||
}
|
||||
}
|
||||
|
||||
Pict pict = movie.getPict(movie.getTime()); // returns an int
|
||||
pict.draw(movieGraphics, movieRect);
|
||||
PixMap pixmap = movieGraphics.getPixMap();
|
||||
raw = pixmap.getPixelData();
|
||||
|
||||
// It needs to get at least a small part
|
||||
// of the video to get the parameters
|
||||
if (firstFrame) {
|
||||
//int intsPerRow = pixmap.getRowBytes() / 4;
|
||||
int movieWidth = movieRect.getWidth();
|
||||
int movieHeight = movieRect.getHeight();
|
||||
int j = raw.getRowBytes() - movieWidth*4;
|
||||
// this doesn't round up.. does it need to?
|
||||
int k = j / 4;
|
||||
int dataWidth = movieWidth + k;
|
||||
|
||||
if (dataWidth != movieWidth) {
|
||||
if (removeBorders) {
|
||||
borderImage = new PImage(dataWidth, movieHeight, RGB);
|
||||
} else {
|
||||
movieWidth = dataWidth;
|
||||
}
|
||||
}
|
||||
//int vpixels[] = new int[movieWidth * movieHeight];
|
||||
//image = new PImage(vpixels, movieWidth, movieHeight, RGB);
|
||||
super.init(movieWidth, movieHeight, RGB);
|
||||
//parent.video = image;
|
||||
firstFrame = false;
|
||||
}
|
||||
// this happens later (found by hernando)
|
||||
//raw.copyToArray(0, image.pixels, 0, image.width * image.height);
|
||||
|
||||
loadPixels();
|
||||
// this is identical to a chunk of code inside PCamera
|
||||
// this might be a candidate to move up to PVideo or something
|
||||
if (borderImage != null) { // need to remove borders
|
||||
raw.copyToArray(0, borderImage.pixels,
|
||||
0, borderImage.width * borderImage.height);
|
||||
int borderIndex = 0;
|
||||
int targetIndex = 0;
|
||||
for (int i = 0; i < height; i++) {
|
||||
System.arraycopy(borderImage.pixels, borderIndex,
|
||||
pixels, targetIndex, width);
|
||||
borderIndex += borderImage.width;
|
||||
targetIndex += width;
|
||||
}
|
||||
} else { // just copy directly
|
||||
raw.copyToArray(0, pixels, 0, width * height);
|
||||
}
|
||||
|
||||
// ready to rock
|
||||
//System.out.println("updating pixels");
|
||||
//updatePixels(); // mark as modified
|
||||
updatePixels();
|
||||
|
||||
} catch (QTException qte) {
|
||||
qte.printStackTrace();
|
||||
//QTSession.close(); // let dispose() handle it
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Begin playing the movie, with no repeat.
|
||||
*/
|
||||
public void play() {
|
||||
// if (runner != null) {
|
||||
// stop();
|
||||
// }
|
||||
play = true;
|
||||
// runner = new Thread(this);
|
||||
// runner.start();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Begin playing the movie, with repeat.
|
||||
*/
|
||||
public void loop() {
|
||||
play();
|
||||
repeat = true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Shut off the repeating loop.
|
||||
*/
|
||||
public void noLoop() {
|
||||
repeat = false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Pause the movie at its current time.
|
||||
*/
|
||||
public void pause() {
|
||||
play = false;
|
||||
//System.out.println("pause");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Stop the movie, and rewind.
|
||||
*/
|
||||
public void stop() {
|
||||
play = false;
|
||||
// runner = null;
|
||||
|
||||
try {
|
||||
movie.setTimeValue(0);
|
||||
|
||||
} catch (StdQTException e) {
|
||||
errorMessage("stop", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set how often new frames are to be read from the movie.
|
||||
* Does not actually set the speed of the movie playback,
|
||||
* that's handled by the speed() method.
|
||||
*/
|
||||
public void frameRate(int ifps) {
|
||||
if (ifps <= 0) {
|
||||
System.err.println("Movie: ignoring bad frame rate of " +
|
||||
ifps + " fps.");
|
||||
} else {
|
||||
fps = ifps;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set a multiplier for how fast/slow the movie should be run.
|
||||
* The default is 1.0.
|
||||
* <UL>
|
||||
* <LI>speed(2) will play the movie at double speed (2x).
|
||||
* <LI>speed(0.5) will play at half speed.
|
||||
* <LI>speed(-1) will play backwards at regular speed.
|
||||
* </UL>
|
||||
*/
|
||||
public void speed(float rate) {
|
||||
//rate = irate;
|
||||
try {
|
||||
movie.setRate(rate);
|
||||
|
||||
} catch (StdQTException e) {
|
||||
errorMessage("speed", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the current time in seconds.
|
||||
* The number is a float so fractions of seconds can be used.
|
||||
*/
|
||||
public float time() {
|
||||
try {
|
||||
return (float)movie.getTime() / (float)movie.getTimeScale();
|
||||
|
||||
} catch (StdQTException e) {
|
||||
errorMessage("time", e);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Jump to a specific location (in seconds).
|
||||
* The number is a float so fractions of seconds can be used.
|
||||
*/
|
||||
public void jump(float where) {
|
||||
try {
|
||||
//movie.setTime(new TimeRecord(rate, where)); // scale, value
|
||||
//movie.setTime(new TimeRecord(1, where)); // scale, value
|
||||
int scaledTime = (int) (where * movie.getTimeScale());
|
||||
movie.setTimeValue(scaledTime);
|
||||
|
||||
} catch (StdQTException e) {
|
||||
errorMessage("jump", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the full length of this movie (in seconds).
|
||||
*/
|
||||
public float duration() {
|
||||
try {
|
||||
return (float)movie.getDuration() / (float)movie.getTimeScale();
|
||||
|
||||
} catch (StdQTException e) {
|
||||
errorMessage("length", e);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
public void play() {
|
||||
if(!play) {
|
||||
play = true;
|
||||
}
|
||||
start();
|
||||
while( image == null) {
|
||||
try {
|
||||
Thread.sleep(5);
|
||||
} catch (InterruptedException e) { }
|
||||
}
|
||||
pixels = image.pixels;
|
||||
width = image.width;
|
||||
height = image.height;
|
||||
}
|
||||
|
||||
|
||||
public void repeat() {
|
||||
loop = true;
|
||||
if(!play) {
|
||||
play = true;
|
||||
}
|
||||
start();
|
||||
while( image == null) {
|
||||
try {
|
||||
Thread.sleep(5);
|
||||
} catch (InterruptedException e) { }
|
||||
}
|
||||
pixels = image.pixels;
|
||||
width = image.width;
|
||||
height = image.height;
|
||||
}
|
||||
|
||||
|
||||
public void pause() {
|
||||
play = false;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
public void run() {
|
||||
//System.out.println("entering thread");
|
||||
while (Thread.currentThread() == runner) {
|
||||
//System.out.print("<");
|
||||
try {
|
||||
//Thread.sleep(5);
|
||||
Thread.sleep(1000 / fps);
|
||||
} catch (InterruptedException e) { }
|
||||
//System.out.print(">");
|
||||
|
||||
// this could be a lie, but..
|
||||
if (play) {
|
||||
//read();
|
||||
//System.out.println("play");
|
||||
available = true;
|
||||
|
||||
if (movieEventMethod == null) {
|
||||
// If no special handling, then automatically read from the movie.
|
||||
read();
|
||||
|
||||
} else {
|
||||
try {
|
||||
movieEventMethod.invoke(parent, new Object[] { this });
|
||||
} catch (Exception e) {
|
||||
System.err.println("error, disabling movieEvent() for " +
|
||||
filename);
|
||||
e.printStackTrace();
|
||||
movieEventMethod = null;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
if (movie.isDone() && repeat) {
|
||||
movie.goToBeginning();
|
||||
}
|
||||
} catch (StdQTException e) {
|
||||
play = false;
|
||||
errorMessage("rewinding", e);
|
||||
}
|
||||
//} else {
|
||||
//System.out.println("no play");
|
||||
}
|
||||
|
||||
//try {
|
||||
//read();
|
||||
//if (movie.isDone() && loop) movie.goToBeginning();
|
||||
|
||||
//} catch (QTException e) {
|
||||
//System.err.println("Movie exception");
|
||||
//e.printStackTrace();
|
||||
//QTSession.close(); ??
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Call this to halt the movie from running, and stop its thread.
|
||||
*/
|
||||
public void dispose() {
|
||||
stop();
|
||||
runner = null;
|
||||
QTSession.close();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* General error reporting, all corraled here just in case
|
||||
* I think of something slightly more intelligent to do.
|
||||
*/
|
||||
protected void errorMessage(String where, Exception e) {
|
||||
parent.die("Error inside Movie." + where + "()", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,335 +0,0 @@
|
||||
/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */
|
||||
|
||||
/*
|
||||
Part of the Processing project - http://processing.org
|
||||
|
||||
Copyright (c) 2006 Daniel Shiffman
|
||||
With minor modifications by Ben Fry for Processing 0125+
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General
|
||||
Public License along with this library; if not, write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
package processing.video;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import quicktime.*;
|
||||
import quicktime.io.*;
|
||||
import quicktime.qd.*;
|
||||
import quicktime.std.*;
|
||||
import quicktime.std.image.*;
|
||||
import quicktime.std.movies.Movie;
|
||||
import quicktime.std.movies.Track;
|
||||
import quicktime.std.movies.media.VideoMedia;
|
||||
import quicktime.util.*;
|
||||
|
||||
import processing.core.*;
|
||||
|
||||
|
||||
/**
|
||||
* Library to create a QuickTime movie from a Processing pixel array.
|
||||
* Written by <A HREF="http://www.shiffman.net">Daniel Shiffman</A>.
|
||||
* Thanks to Dan O'Sullivan and Shawn Van Every.
|
||||
* <BR> <BR>
|
||||
* Please note that some constructors and variable names were altered
|
||||
* slightly when the library was added to the Processing distribution.
|
||||
* <PRE>
|
||||
* // Declare MovieMaker object
|
||||
* MovieMaker mm;
|
||||
*
|
||||
* void setup() {
|
||||
* size(320, 240);
|
||||
*
|
||||
* // Create MovieMaker object with size, filename,
|
||||
* // compression codec and quality, framerate
|
||||
* mm = new MovieMaker(this, width, height, "drawing.mov", 30,
|
||||
* MovieMaker.H263, MovieMaker.HIGH);
|
||||
* background(160, 32, 32);
|
||||
* }
|
||||
*
|
||||
* void draw() {
|
||||
* stroke(7, 146, 168);
|
||||
* strokeWeight(4);
|
||||
*
|
||||
* // Draw if mouse is pressed
|
||||
* if (mousePressed) {
|
||||
* line(pmouseX, pmouseY, mouseX, mouseY);
|
||||
* }
|
||||
*
|
||||
* // Add window's pixels to movie
|
||||
* mm.addFrame();
|
||||
* }
|
||||
*
|
||||
* void keyPressed() {
|
||||
* // Finish the movie if space bar is pressed!
|
||||
* if (key == ' ') {
|
||||
* mm.finish();
|
||||
* }
|
||||
* }
|
||||
* </PRE>
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public class MovieMaker {
|
||||
public static final int RAW = StdQTConstants.kRawCodecType;
|
||||
public static final int ANIMATION = StdQTConstants.kAnimationCodecType;
|
||||
public static final int BASE = StdQTConstants.kBaseCodecType;
|
||||
public static final int BMP = StdQTConstants.kBMPCodecType;
|
||||
public static final int CINEPAK = StdQTConstants.kCinepakCodecType;
|
||||
public static final int COMPONENT = StdQTConstants.kComponentVideoCodecType;
|
||||
public static final int CMYK = StdQTConstants.kCMYKCodecType;
|
||||
public static final int GIF = StdQTConstants.kGIFCodecType;
|
||||
public static final int GRAPHICS = StdQTConstants.kGraphicsCodecType;
|
||||
public static final int H261 = StdQTConstants.kH261CodecType;
|
||||
public static final int H263 = StdQTConstants.kH263CodecType;
|
||||
// H.264 encoding, added because no constant is available in QTJava
|
||||
public static final int H264 = QTUtils.toOSType("avc1");
|
||||
public static final int JPEG = StdQTConstants.kJPEGCodecType;
|
||||
public static final int MS_VIDEO = StdQTConstants.kMicrosoftVideo1CodecType;
|
||||
public static final int MOTION_JPEG_A = StdQTConstants.kMotionJPEGACodecType;
|
||||
public static final int MOTION_JPEG_B = StdQTConstants.kMotionJPEGBCodecType;
|
||||
public static final int SORENSON = StdQTConstants.kSorensonCodecType;
|
||||
public static final int VIDEO = StdQTConstants.kVideoCodecType;
|
||||
|
||||
public static final int WORST = StdQTConstants.codecMinQuality;
|
||||
public static final int LOW = StdQTConstants.codecLowQuality;
|
||||
public static final int MEDIUM = StdQTConstants.codecNormalQuality;
|
||||
public static final int HIGH = StdQTConstants.codecHighQuality;
|
||||
public static final int BEST = StdQTConstants.codecMaxQuality;
|
||||
public static final int LOSSLESS = StdQTConstants.codecLosslessQuality;
|
||||
|
||||
private int width;
|
||||
private int height;
|
||||
|
||||
private boolean readyForFrames;
|
||||
|
||||
// Changed from 1000 to 600 in release 0154 to enable exact 30 fps output.
|
||||
// http://dev.processing.org/bugs/show_bug.cgi?id=988
|
||||
private int TIME_SCALE = 600;
|
||||
|
||||
// QT Stuff
|
||||
private VideoMedia videoMedia;
|
||||
private Track videoTrack;
|
||||
private Movie movie;
|
||||
private QTFile movFile;
|
||||
private CSequence seq;
|
||||
private QTHandle imageHandle;
|
||||
private QDGraphics gw;
|
||||
private QDRect bounds;
|
||||
private ImageDescription imgDesc;
|
||||
private RawEncodedImage compressedImage;
|
||||
|
||||
private int rate;
|
||||
private int keyFrameRate = 15;
|
||||
private int codecType, codecQuality;
|
||||
|
||||
// my hack to make sure we don't get error -8691
|
||||
private boolean temporalSupported = true;
|
||||
|
||||
private PApplet parent;
|
||||
|
||||
|
||||
/**
|
||||
* Create a movie with the specified width, height, and filename.
|
||||
* The movie will be created at 15 frames per second.
|
||||
* The codec will be set to RAW and quality set to HIGH.
|
||||
*/
|
||||
public MovieMaker(PApplet p, int _w, int _h, String _filename) {
|
||||
this(p, _w, _h, _filename, 30, RAW, HIGH, 15);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a movie with the specified width, height, filename, and frame rate.
|
||||
* The codec will be set to RAW and quality set to HIGH.
|
||||
*/
|
||||
public MovieMaker(PApplet p, int _w, int _h, String _filename, int _rate) {
|
||||
this(p, _w, _h, _filename, _rate, RAW, HIGH, 15);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a movie with the specified width, height, filename, frame rate,
|
||||
* and codec type and quality. Key frames will be set at 15 frames.
|
||||
*/
|
||||
public MovieMaker(PApplet p, int _w, int _h, String _filename, int _rate,
|
||||
int _codecType, int _codecQuality) {
|
||||
this(p, _w, _h, _filename, _rate, _codecType, _codecQuality, 15);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a movie with the specified width, height, filename, frame rate,
|
||||
* codec type and quality, and key frame rate.
|
||||
*/
|
||||
public MovieMaker(PApplet p, int _w, int _h, String _filename, int _rate,
|
||||
int _codecType, int _codecQuality,
|
||||
int _keyFrameRate) {
|
||||
parent = p;
|
||||
|
||||
width = _w;
|
||||
height = _h;
|
||||
rate = _rate;
|
||||
|
||||
try {
|
||||
QTSession.open();
|
||||
} catch (QTException e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
|
||||
try {
|
||||
ImageDescription imgD = null;
|
||||
if (quicktime.util.EndianOrder.isNativeLittleEndian()) {
|
||||
imgD = new ImageDescription(QDConstants.k32BGRAPixelFormat);
|
||||
} else {
|
||||
imgD = new ImageDescription(QDGraphics.kDefaultPixelFormat);
|
||||
}
|
||||
imgD.setWidth(width);
|
||||
imgD.setHeight(height);
|
||||
gw = new QDGraphics(imgD, 0);
|
||||
|
||||
} catch (QTException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
codecType = _codecType;
|
||||
codecQuality = _codecQuality;
|
||||
keyFrameRate = _keyFrameRate;
|
||||
initMovie(_filename);
|
||||
|
||||
parent.registerDispose(this);
|
||||
}
|
||||
|
||||
|
||||
private void initMovie(String filename) {
|
||||
try {
|
||||
String path = parent.savePath(filename);
|
||||
movFile = new QTFile(new File(path));
|
||||
movie = Movie.createMovieFile(movFile, StdQTConstants.kMoviePlayer, StdQTConstants.createMovieFileDeleteCurFile);
|
||||
int timeScale = TIME_SCALE; // 100 units per second
|
||||
videoTrack = movie.addTrack(width, height, 0);
|
||||
videoMedia = new VideoMedia(videoTrack, timeScale);
|
||||
videoMedia.beginEdits();
|
||||
bounds = new QDRect(0, 0, width, height);
|
||||
int rawImageSize = QTImage.getMaxCompressionSize(gw, bounds, gw.getPixMap().getPixelSize(), codecQuality, codecType, CodecComponent.anyCodec);
|
||||
imageHandle = new QTHandle(rawImageSize, true);
|
||||
imageHandle.lock();
|
||||
compressedImage = RawEncodedImage.fromQTHandle(imageHandle);
|
||||
seq = new CSequence(gw, bounds, gw.getPixMap().getPixelSize(), codecType, CodecComponent.bestFidelityCodec, codecQuality, codecQuality, keyFrameRate, null, 0);
|
||||
imgDesc = seq.getDescription();
|
||||
readyForFrames = true;
|
||||
|
||||
} catch (QTException e) {
|
||||
if (e.errorCode() == Errors.noCodecErr) {
|
||||
if (imageHandle == null) {
|
||||
// This means QTImage.getMaxCompressionSize() failed
|
||||
System.err.println("The specified codec is not supported, " +
|
||||
"please ensure that the parameters are valid, " +
|
||||
"and in the correct order.");
|
||||
} else {
|
||||
// If it's a -8961 error, quietly do it the other way
|
||||
// (this happens when RAW is specified)
|
||||
temporalSupported = false;
|
||||
readyForFrames = true;
|
||||
}
|
||||
|
||||
} else if (e.errorCode() == Errors.fBsyErr) {
|
||||
System.err.println("The movie file already exists. " +
|
||||
"Please delete it first.");
|
||||
|
||||
} else {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// A simple add function to just add whatever is in the parent window
|
||||
public void addFrame() {
|
||||
// http://dev.processing.org/bugs/show_bug.cgi?id=692
|
||||
parent.flush();
|
||||
parent.loadPixels();
|
||||
addFrame(parent.pixels, parent.width, parent.height);
|
||||
}
|
||||
|
||||
|
||||
public void addFrame(int[] _pixels, int w, int h) {
|
||||
if (readyForFrames){
|
||||
RawEncodedImage pixelData = gw.getPixMap().getPixelData();
|
||||
int rowBytes = pixelData.getRowBytes() / 4;
|
||||
int[] newpixels = new int[rowBytes*h];
|
||||
for (int i = 0; i < rowBytes; i++) {
|
||||
for (int j = 0; j < h; j++) {
|
||||
if (i < w) {
|
||||
newpixels[i+j*rowBytes] = _pixels[i+j*w];
|
||||
} else {
|
||||
newpixels[i+j*rowBytes] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
pixelData.setInts(0,newpixels);
|
||||
compressAndAdd();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void compressAndAdd() {
|
||||
try {
|
||||
if (temporalSupported) {
|
||||
CompressedFrameInfo cfInfo = seq.compressFrame(gw, bounds, StdQTConstants.codecFlagUpdatePrevious, compressedImage);
|
||||
boolean syncSample = cfInfo.getSimilarity() == 0; // see developer.apple.com/qa/qtmcc/qtmcc20.html
|
||||
videoMedia.addSample(imageHandle, 0, cfInfo.getDataSize(), TIME_SCALE/rate, imgDesc, 1, syncSample ? 0 : StdQTConstants.mediaSampleNotSync);
|
||||
} else {
|
||||
imgDesc = QTImage.fCompress(gw,gw.getBounds(),32,codecQuality,codecType, CodecComponent.anyCodec, null, 0, RawEncodedImage.fromQTHandle(imageHandle));
|
||||
boolean syncSample = true; // UM, what the hell should this be???
|
||||
videoMedia.addSample(imageHandle, 0, imgDesc.getDataSize(), TIME_SCALE/rate, imgDesc, 1, syncSample ? 0 : StdQTConstants.mediaSampleNotSync);
|
||||
}
|
||||
} catch (QTException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Close out and finish the movie file.
|
||||
*/
|
||||
public void finish() {
|
||||
try {
|
||||
if (readyForFrames) {
|
||||
//System.out.println("Finishing movie file.");
|
||||
readyForFrames = false;
|
||||
videoMedia.endEdits();
|
||||
videoTrack.insertMedia(0, 0, videoMedia.getDuration(), 1);
|
||||
OpenMovieFile omf = OpenMovieFile.asWrite(movFile);
|
||||
movie.addResource(omf, StdQTConstants.movieInDataForkResID,
|
||||
movFile.getName());
|
||||
}
|
||||
} catch (StdQTException se) {
|
||||
se.printStackTrace();
|
||||
} catch (QTException qe) {
|
||||
qe.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void dispose() {
|
||||
if (readyForFrames) finish();
|
||||
|
||||
try {
|
||||
QTSession.close();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user