File size: 9,952 Bytes
2bffcbb 35a93a9 2bffcbb 35a93a9 2bffcbb |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 |
import base64
import requests
from PIL import Image
import io
import json
import logging
import json
import pandas as pd
import re
IMAGE_ANALYSES_KEY = "Image Analyses"
# Configure logging
logging.basicConfig(level=logging.INFO)
import os
api_key = os.environ.get("OPENAI_API_KEY")
# Function to encode the image to base64
def encode_image(image_path):
try:
with Image.open(image_path) as img:
img.thumbnail((800, 800)) # Resize image
buffer = io.BytesIO()
img.save(buffer, format="JPEG", quality=85)
encoded_image = base64.b64encode(buffer.getvalue()).decode('utf-8')
return encoded_image
except Exception as e:
logging.error(f"Failed to encode image {image_path}: {e}")
return None
# Function to get image dimensions
def get_image_dimensions(image_path):
try:
with Image.open(image_path) as img:
return img.size # returns (width, height)
except Exception as e:
logging.error(f"Failed to get dimensions for image {image_path}: {e}")
return (0, 0)
# Image paths for analysis
image_paths = [
"data/competitor/image1.jpeg",
"data/competitor/image2.jpeg",
"data/competitor/image3.jpeg",
"data/competitor/image4.jpeg",
"data/competitor/image5.jpeg",
"data/competitor/image6.jpeg"
]
# Headers for the OpenAI API request
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {api_key}"
}
# Competitor information (context for analysis)
competitor_information = """
The competitor is a leading brand in the digital marketing space known for its consistent visual branding and innovative designs on social media. They target a tech-savvy audience aged 20-35 with a focus on modern aesthetics, engaging storytelling, and minimalist yet powerful branding.
"""
system_message = """
Analyze the branding, content marketing, and social media marketing effectiveness of a company for the provided Instagram post image.
Evaluate it based on the following criteria and return a detailed JSON structure. Each criterion should have an individual score (0-10), and the total score for the category should be the average of its criteria.
Give 9 or above only when it's extraordinary. Industry standard 7-8
### Categories and Definitions:
#### Branding:
- **Logo Placement**: Is the logo perfectly sized, clearly visible, and well-positioned without being intrusive?
- **Brand Colors**: Are brand colors used consistently and without deviations?
- **Typography**: Are the fonts aligned with the brand identity, consistent in style, and visually appealing?
- **Brand Identity**: Does the post effectively reflect the brand's unique persona and messaging?
- **Visual Hierarchy**: Are key elements prioritized effectively to guide the viewer’s attention?
- **Template Consistency**: Are templates consistent with previous posts, reflecting a uniform design approach?
- **Messaging Alignment**: Is the brand messaging clear, consistent, and reflective of the brand's tone?
- **Subtle Branding**: Does the branding strike the right balance (not overly subtle or excessive)?
- **Overbranding**: Does the post avoid overwhelming and distracting brand elements?
- **Creative Variations**: Are there innovative and creative design variations in the post?
#### Content Marketing:
- **Content Visibility**: Is the primary content clear and highlighted effectively?
- **Engagement Cues**: Are clear and compelling calls-to-action (CTAs) present and engaging?
- **Information Overload**: Does the post avoid over-saturated visuals or excessive text?
- **Storytelling**: Does the post convey a relevant and engaging narrative that resonates with the audience?
- **Content Variety**: Are the posts diverse and free of monotonous or repetitive elements?
- **Typography Consistency**: Is the typography visually attractive and consistent throughout the design?
- **Aesthetic Coherence**: Do all elements harmonize to create a visually appealing composition?
- **Content Relevance**: Is the content relevant to the brand and its target audience?
- **Stock Elements**: Does the design avoid excessive use of generic or stock imagery?
#### Social Media Marketing:
- **Font Size**: Are fonts appropriately sized and legible on various screen sizes?
- **Visibility of Text**: Is the text easy to read, with proper contrast, placement, and spacing?
- **Logo Placement**: Does the logo placement avoid disrupting the design's aesthetic appeal?
- **Consistency**: Does the post maintain design cohesion across elements?
- **Alignment**: Are elements aligned professionally, creating a balanced and clean layout?
- **Aesthetic Appeal**: Is the overall design visually engaging and suitable for the platform?
- **Brand Elements**: Are brand assets (like logos, icons, or visuals) used effectively and sparingly?
- **Repetitiveness**: Does the design avoid repetitive themes and offer fresh creative ideas?
### Output JSON Format:
### Only return the following format strictly
{
"Branding Score": total_avg_score, explanation.
"criteria_name": score, explanation.
"criteria_name": score, explanation.
"Content Marketing Score": total_avg_score, explanation.
"criteria_name": score, explanation.
"criteria_name": score, explanation.
"Social Media Marketing Score": total_avg_score, explanation.
"criteria_name": score, explanation.
"criteria_name": score, explanation.
}
"""
# Function to request analysis from OpenAI API
def request_analysis(system_message, user_message, model="gpt-4o-mini", max_tokens=1500):
payload = {
"model": model,
"messages": [
{"role": "system", "content": system_message},
{"role": "user", "content": user_message}
],
"max_tokens": max_tokens
}
logging.debug(f"Payload Sent: {json.dumps(payload, indent=4)}")
response = requests.post("https://api.openai.com/v1/chat/completions", headers=headers, json=payload)
if response.status_code == 200:
try:
return response.json().get("choices", [{}])[0].get("message", {}).get("content", "Unexpected response format")
except Exception as e:
logging.error(f"Error parsing response: {e}")
logging.debug(f"Raw Response: {response.text}")
return "Error parsing the response."
else:
logging.error(f"API Error: {response.status_code}, {response.text}")
return "Error with the API request."
# Initialize structured output for the analyses
output_structure = {
IMAGE_ANALYSES_KEY: []
}
# Loop through each image for analysis
for image_path in image_paths:
base64_image = encode_image(image_path)
if not base64_image:
output_structure[IMAGE_ANALYSES_KEY].append({
"Image": image_path,
"Analysis": "Failed to encode image."
})
continue
width, height = get_image_dimensions(image_path)
user_message = f"""
Company Information: {competitor_information}
Analyze the Instagram post with dimensions {width}x{height} pixels. Image data: {base64_image}
"""
try:
analysis_result = request_analysis(system_message, user_message)
try:
# Parse result and ensure it matches the required format
parsed_result = json.loads(analysis_result)
except json.JSONDecodeError:
logging.warning(f"Response not in expected JSON format for {image_path}: {analysis_result}")
parsed_result = {"Raw Response": analysis_result}
output_structure[IMAGE_ANALYSES_KEY].append({
"Image": image_path,
"Analysis": parsed_result
})
except Exception as err:
logging.error(f"Error analyzing image {image_path}: {err}")
output_structure[IMAGE_ANALYSES_KEY].append({
"Image": image_path,
"Analysis": "Error analyzing the image."
})
# Write structured output to file
with open("Output_File/json/competitor_analysis.json", "w") as f:
json.dump(output_structure, f, indent=4)
logging.info("Analysis completed and saved to competitor_analysis.json")
def json_to_excel(json_file, excel_file):
"""
Parse the JSON file and convert it to an Excel file with structured scores and raw JSON responses.
Args:
json_file (str): Path to the input JSON file.
excel_file (str): Path to the output Excel file.
"""
# Load JSON data from the file
with open(json_file, 'r') as file:
data = json.load(file)
# Prepare a list to hold structured data
structured_data = []
# Regex patterns to extract scores and criteria
score_pattern = r'"([a-zA-Z\s]+)":\s*(\d+),' # Matches "Criteria Name": Score,
# Iterate over "Image Analyses" entries
for analysis in data.get("Image Analyses", []):
# Extract image name
image = analysis.get("Image", "Unknown")
# Extract raw response
raw_response = analysis.get("Analysis", {}).get("Raw Response", "")
# Dictionary to hold extracted data for the image
image_data = {"Image": image, "Raw JSON Response": raw_response}
# Extract criteria and scores using regex
matches = re.findall(score_pattern, raw_response)
for criterion, score in matches:
image_data[criterion.strip()] = int(score) # Add criteria as columns
# Append image data to structured list
structured_data.append(image_data)
# Convert structured data to DataFrame
df = pd.DataFrame(structured_data)
# Write DataFrame to Excel
df.to_excel(excel_file, index=False)
print(f"Data successfully written to {excel_file}")
# Example usage
json_file_path = "Output_File/json/competitor_analysis.json" # Input JSON file
excel_file_path = "Output_File/excel/competitor_analysis.xlsx" # Output Excel file
json_to_excel(json_file_path, excel_file_path)
|